##// END OF EJS Templates
debugbundle: also display if a part is mandatory or advisory...
Boris Feld -
r37919:d618558e stable
parent child Browse files
Show More
@@ -1,3135 +1,3136 b''
1 1 # debugcommands.py - command processing for debug* commands
2 2 #
3 3 # Copyright 2005-2016 Matt Mackall <mpm@selenic.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from __future__ import absolute_import
9 9
10 10 import codecs
11 11 import collections
12 12 import difflib
13 13 import errno
14 14 import operator
15 15 import os
16 16 import random
17 17 import re
18 18 import socket
19 19 import ssl
20 20 import stat
21 21 import string
22 22 import subprocess
23 23 import sys
24 24 import tempfile
25 25 import time
26 26
27 27 from .i18n import _
28 28 from .node import (
29 29 bin,
30 30 hex,
31 31 nullhex,
32 32 nullid,
33 33 nullrev,
34 34 short,
35 35 )
36 36 from .thirdparty import (
37 37 cbor,
38 38 )
39 39 from . import (
40 40 bundle2,
41 41 changegroup,
42 42 cmdutil,
43 43 color,
44 44 context,
45 45 dagparser,
46 46 dagutil,
47 47 encoding,
48 48 error,
49 49 exchange,
50 50 extensions,
51 51 filemerge,
52 52 fileset,
53 53 formatter,
54 54 hg,
55 55 httppeer,
56 56 localrepo,
57 57 lock as lockmod,
58 58 logcmdutil,
59 59 merge as mergemod,
60 60 obsolete,
61 61 obsutil,
62 62 phases,
63 63 policy,
64 64 pvec,
65 65 pycompat,
66 66 registrar,
67 67 repair,
68 68 revlog,
69 69 revset,
70 70 revsetlang,
71 71 scmutil,
72 72 setdiscovery,
73 73 simplemerge,
74 74 smartset,
75 75 sshpeer,
76 76 sslutil,
77 77 streamclone,
78 78 templater,
79 79 treediscovery,
80 80 upgrade,
81 81 url as urlmod,
82 82 util,
83 83 vfs as vfsmod,
84 84 wireprotoframing,
85 85 wireprotoserver,
86 86 wireprotov2peer,
87 87 )
88 88 from .utils import (
89 89 dateutil,
90 90 procutil,
91 91 stringutil,
92 92 )
93 93
94 94 release = lockmod.release
95 95
96 96 command = registrar.command()
97 97
98 98 @command('debugancestor', [], _('[INDEX] REV1 REV2'), optionalrepo=True)
99 99 def debugancestor(ui, repo, *args):
100 100 """find the ancestor revision of two revisions in a given index"""
101 101 if len(args) == 3:
102 102 index, rev1, rev2 = args
103 103 r = revlog.revlog(vfsmod.vfs(pycompat.getcwd(), audit=False), index)
104 104 lookup = r.lookup
105 105 elif len(args) == 2:
106 106 if not repo:
107 107 raise error.Abort(_('there is no Mercurial repository here '
108 108 '(.hg not found)'))
109 109 rev1, rev2 = args
110 110 r = repo.changelog
111 111 lookup = repo.lookup
112 112 else:
113 113 raise error.Abort(_('either two or three arguments required'))
114 114 a = r.ancestor(lookup(rev1), lookup(rev2))
115 115 ui.write('%d:%s\n' % (r.rev(a), hex(a)))
116 116
117 117 @command('debugapplystreamclonebundle', [], 'FILE')
118 118 def debugapplystreamclonebundle(ui, repo, fname):
119 119 """apply a stream clone bundle file"""
120 120 f = hg.openpath(ui, fname)
121 121 gen = exchange.readbundle(ui, f, fname)
122 122 gen.apply(repo)
123 123
124 124 @command('debugbuilddag',
125 125 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
126 126 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
127 127 ('n', 'new-file', None, _('add new file at each rev'))],
128 128 _('[OPTION]... [TEXT]'))
129 129 def debugbuilddag(ui, repo, text=None,
130 130 mergeable_file=False,
131 131 overwritten_file=False,
132 132 new_file=False):
133 133 """builds a repo with a given DAG from scratch in the current empty repo
134 134
135 135 The description of the DAG is read from stdin if not given on the
136 136 command line.
137 137
138 138 Elements:
139 139
140 140 - "+n" is a linear run of n nodes based on the current default parent
141 141 - "." is a single node based on the current default parent
142 142 - "$" resets the default parent to null (implied at the start);
143 143 otherwise the default parent is always the last node created
144 144 - "<p" sets the default parent to the backref p
145 145 - "*p" is a fork at parent p, which is a backref
146 146 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
147 147 - "/p2" is a merge of the preceding node and p2
148 148 - ":tag" defines a local tag for the preceding node
149 149 - "@branch" sets the named branch for subsequent nodes
150 150 - "#...\\n" is a comment up to the end of the line
151 151
152 152 Whitespace between the above elements is ignored.
153 153
154 154 A backref is either
155 155
156 156 - a number n, which references the node curr-n, where curr is the current
157 157 node, or
158 158 - the name of a local tag you placed earlier using ":tag", or
159 159 - empty to denote the default parent.
160 160
161 161 All string valued-elements are either strictly alphanumeric, or must
162 162 be enclosed in double quotes ("..."), with "\\" as escape character.
163 163 """
164 164
165 165 if text is None:
166 166 ui.status(_("reading DAG from stdin\n"))
167 167 text = ui.fin.read()
168 168
169 169 cl = repo.changelog
170 170 if len(cl) > 0:
171 171 raise error.Abort(_('repository is not empty'))
172 172
173 173 # determine number of revs in DAG
174 174 total = 0
175 175 for type, data in dagparser.parsedag(text):
176 176 if type == 'n':
177 177 total += 1
178 178
179 179 if mergeable_file:
180 180 linesperrev = 2
181 181 # make a file with k lines per rev
182 182 initialmergedlines = ['%d' % i for i in xrange(0, total * linesperrev)]
183 183 initialmergedlines.append("")
184 184
185 185 tags = []
186 186
187 187 wlock = lock = tr = None
188 188 try:
189 189 wlock = repo.wlock()
190 190 lock = repo.lock()
191 191 tr = repo.transaction("builddag")
192 192
193 193 at = -1
194 194 atbranch = 'default'
195 195 nodeids = []
196 196 id = 0
197 197 ui.progress(_('building'), id, unit=_('revisions'), total=total)
198 198 for type, data in dagparser.parsedag(text):
199 199 if type == 'n':
200 200 ui.note(('node %s\n' % pycompat.bytestr(data)))
201 201 id, ps = data
202 202
203 203 files = []
204 204 filecontent = {}
205 205
206 206 p2 = None
207 207 if mergeable_file:
208 208 fn = "mf"
209 209 p1 = repo[ps[0]]
210 210 if len(ps) > 1:
211 211 p2 = repo[ps[1]]
212 212 pa = p1.ancestor(p2)
213 213 base, local, other = [x[fn].data() for x in (pa, p1,
214 214 p2)]
215 215 m3 = simplemerge.Merge3Text(base, local, other)
216 216 ml = [l.strip() for l in m3.merge_lines()]
217 217 ml.append("")
218 218 elif at > 0:
219 219 ml = p1[fn].data().split("\n")
220 220 else:
221 221 ml = initialmergedlines
222 222 ml[id * linesperrev] += " r%i" % id
223 223 mergedtext = "\n".join(ml)
224 224 files.append(fn)
225 225 filecontent[fn] = mergedtext
226 226
227 227 if overwritten_file:
228 228 fn = "of"
229 229 files.append(fn)
230 230 filecontent[fn] = "r%i\n" % id
231 231
232 232 if new_file:
233 233 fn = "nf%i" % id
234 234 files.append(fn)
235 235 filecontent[fn] = "r%i\n" % id
236 236 if len(ps) > 1:
237 237 if not p2:
238 238 p2 = repo[ps[1]]
239 239 for fn in p2:
240 240 if fn.startswith("nf"):
241 241 files.append(fn)
242 242 filecontent[fn] = p2[fn].data()
243 243
244 244 def fctxfn(repo, cx, path):
245 245 if path in filecontent:
246 246 return context.memfilectx(repo, cx, path,
247 247 filecontent[path])
248 248 return None
249 249
250 250 if len(ps) == 0 or ps[0] < 0:
251 251 pars = [None, None]
252 252 elif len(ps) == 1:
253 253 pars = [nodeids[ps[0]], None]
254 254 else:
255 255 pars = [nodeids[p] for p in ps]
256 256 cx = context.memctx(repo, pars, "r%i" % id, files, fctxfn,
257 257 date=(id, 0),
258 258 user="debugbuilddag",
259 259 extra={'branch': atbranch})
260 260 nodeid = repo.commitctx(cx)
261 261 nodeids.append(nodeid)
262 262 at = id
263 263 elif type == 'l':
264 264 id, name = data
265 265 ui.note(('tag %s\n' % name))
266 266 tags.append("%s %s\n" % (hex(repo.changelog.node(id)), name))
267 267 elif type == 'a':
268 268 ui.note(('branch %s\n' % data))
269 269 atbranch = data
270 270 ui.progress(_('building'), id, unit=_('revisions'), total=total)
271 271 tr.close()
272 272
273 273 if tags:
274 274 repo.vfs.write("localtags", "".join(tags))
275 275 finally:
276 276 ui.progress(_('building'), None)
277 277 release(tr, lock, wlock)
278 278
279 279 def _debugchangegroup(ui, gen, all=None, indent=0, **opts):
280 280 indent_string = ' ' * indent
281 281 if all:
282 282 ui.write(("%sformat: id, p1, p2, cset, delta base, len(delta)\n")
283 283 % indent_string)
284 284
285 285 def showchunks(named):
286 286 ui.write("\n%s%s\n" % (indent_string, named))
287 287 for deltadata in gen.deltaiter():
288 288 node, p1, p2, cs, deltabase, delta, flags = deltadata
289 289 ui.write("%s%s %s %s %s %s %d\n" %
290 290 (indent_string, hex(node), hex(p1), hex(p2),
291 291 hex(cs), hex(deltabase), len(delta)))
292 292
293 293 chunkdata = gen.changelogheader()
294 294 showchunks("changelog")
295 295 chunkdata = gen.manifestheader()
296 296 showchunks("manifest")
297 297 for chunkdata in iter(gen.filelogheader, {}):
298 298 fname = chunkdata['filename']
299 299 showchunks(fname)
300 300 else:
301 301 if isinstance(gen, bundle2.unbundle20):
302 302 raise error.Abort(_('use debugbundle2 for this file'))
303 303 chunkdata = gen.changelogheader()
304 304 for deltadata in gen.deltaiter():
305 305 node, p1, p2, cs, deltabase, delta, flags = deltadata
306 306 ui.write("%s%s\n" % (indent_string, hex(node)))
307 307
308 308 def _debugobsmarkers(ui, part, indent=0, **opts):
309 309 """display version and markers contained in 'data'"""
310 310 opts = pycompat.byteskwargs(opts)
311 311 data = part.read()
312 312 indent_string = ' ' * indent
313 313 try:
314 314 version, markers = obsolete._readmarkers(data)
315 315 except error.UnknownVersion as exc:
316 316 msg = "%sunsupported version: %s (%d bytes)\n"
317 317 msg %= indent_string, exc.version, len(data)
318 318 ui.write(msg)
319 319 else:
320 320 msg = "%sversion: %d (%d bytes)\n"
321 321 msg %= indent_string, version, len(data)
322 322 ui.write(msg)
323 323 fm = ui.formatter('debugobsolete', opts)
324 324 for rawmarker in sorted(markers):
325 325 m = obsutil.marker(None, rawmarker)
326 326 fm.startitem()
327 327 fm.plain(indent_string)
328 328 cmdutil.showmarker(fm, m)
329 329 fm.end()
330 330
331 331 def _debugphaseheads(ui, data, indent=0):
332 332 """display version and markers contained in 'data'"""
333 333 indent_string = ' ' * indent
334 334 headsbyphase = phases.binarydecode(data)
335 335 for phase in phases.allphases:
336 336 for head in headsbyphase[phase]:
337 337 ui.write(indent_string)
338 338 ui.write('%s %s\n' % (hex(head), phases.phasenames[phase]))
339 339
340 340 def _quasirepr(thing):
341 341 if isinstance(thing, (dict, util.sortdict, collections.OrderedDict)):
342 342 return '{%s}' % (
343 343 b', '.join(b'%s: %s' % (k, thing[k]) for k in sorted(thing)))
344 344 return pycompat.bytestr(repr(thing))
345 345
346 346 def _debugbundle2(ui, gen, all=None, **opts):
347 347 """lists the contents of a bundle2"""
348 348 if not isinstance(gen, bundle2.unbundle20):
349 349 raise error.Abort(_('not a bundle2 file'))
350 350 ui.write(('Stream params: %s\n' % _quasirepr(gen.params)))
351 351 parttypes = opts.get(r'part_type', [])
352 352 for part in gen.iterparts():
353 353 if parttypes and part.type not in parttypes:
354 354 continue
355 ui.write('%s -- %s\n' % (part.type, _quasirepr(part.params)))
355 msg = '%s -- %s (mandatory: %r)\n'
356 ui.write((msg % (part.type, _quasirepr(part.params), part.mandatory)))
356 357 if part.type == 'changegroup':
357 358 version = part.params.get('version', '01')
358 359 cg = changegroup.getunbundler(version, part, 'UN')
359 360 if not ui.quiet:
360 361 _debugchangegroup(ui, cg, all=all, indent=4, **opts)
361 362 if part.type == 'obsmarkers':
362 363 if not ui.quiet:
363 364 _debugobsmarkers(ui, part, indent=4, **opts)
364 365 if part.type == 'phase-heads':
365 366 if not ui.quiet:
366 367 _debugphaseheads(ui, part, indent=4)
367 368
368 369 @command('debugbundle',
369 370 [('a', 'all', None, _('show all details')),
370 371 ('', 'part-type', [], _('show only the named part type')),
371 372 ('', 'spec', None, _('print the bundlespec of the bundle'))],
372 373 _('FILE'),
373 374 norepo=True)
374 375 def debugbundle(ui, bundlepath, all=None, spec=None, **opts):
375 376 """lists the contents of a bundle"""
376 377 with hg.openpath(ui, bundlepath) as f:
377 378 if spec:
378 379 spec = exchange.getbundlespec(ui, f)
379 380 ui.write('%s\n' % spec)
380 381 return
381 382
382 383 gen = exchange.readbundle(ui, f, bundlepath)
383 384 if isinstance(gen, bundle2.unbundle20):
384 385 return _debugbundle2(ui, gen, all=all, **opts)
385 386 _debugchangegroup(ui, gen, all=all, **opts)
386 387
387 388 @command('debugcapabilities',
388 389 [], _('PATH'),
389 390 norepo=True)
390 391 def debugcapabilities(ui, path, **opts):
391 392 """lists the capabilities of a remote peer"""
392 393 opts = pycompat.byteskwargs(opts)
393 394 peer = hg.peer(ui, opts, path)
394 395 caps = peer.capabilities()
395 396 ui.write(('Main capabilities:\n'))
396 397 for c in sorted(caps):
397 398 ui.write((' %s\n') % c)
398 399 b2caps = bundle2.bundle2caps(peer)
399 400 if b2caps:
400 401 ui.write(('Bundle2 capabilities:\n'))
401 402 for key, values in sorted(b2caps.iteritems()):
402 403 ui.write((' %s\n') % key)
403 404 for v in values:
404 405 ui.write((' %s\n') % v)
405 406
406 407 @command('debugcheckstate', [], '')
407 408 def debugcheckstate(ui, repo):
408 409 """validate the correctness of the current dirstate"""
409 410 parent1, parent2 = repo.dirstate.parents()
410 411 m1 = repo[parent1].manifest()
411 412 m2 = repo[parent2].manifest()
412 413 errors = 0
413 414 for f in repo.dirstate:
414 415 state = repo.dirstate[f]
415 416 if state in "nr" and f not in m1:
416 417 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
417 418 errors += 1
418 419 if state in "a" and f in m1:
419 420 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
420 421 errors += 1
421 422 if state in "m" and f not in m1 and f not in m2:
422 423 ui.warn(_("%s in state %s, but not in either manifest\n") %
423 424 (f, state))
424 425 errors += 1
425 426 for f in m1:
426 427 state = repo.dirstate[f]
427 428 if state not in "nrm":
428 429 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
429 430 errors += 1
430 431 if errors:
431 432 error = _(".hg/dirstate inconsistent with current parent's manifest")
432 433 raise error.Abort(error)
433 434
434 435 @command('debugcolor',
435 436 [('', 'style', None, _('show all configured styles'))],
436 437 'hg debugcolor')
437 438 def debugcolor(ui, repo, **opts):
438 439 """show available color, effects or style"""
439 440 ui.write(('color mode: %s\n') % ui._colormode)
440 441 if opts.get(r'style'):
441 442 return _debugdisplaystyle(ui)
442 443 else:
443 444 return _debugdisplaycolor(ui)
444 445
445 446 def _debugdisplaycolor(ui):
446 447 ui = ui.copy()
447 448 ui._styles.clear()
448 449 for effect in color._activeeffects(ui).keys():
449 450 ui._styles[effect] = effect
450 451 if ui._terminfoparams:
451 452 for k, v in ui.configitems('color'):
452 453 if k.startswith('color.'):
453 454 ui._styles[k] = k[6:]
454 455 elif k.startswith('terminfo.'):
455 456 ui._styles[k] = k[9:]
456 457 ui.write(_('available colors:\n'))
457 458 # sort label with a '_' after the other to group '_background' entry.
458 459 items = sorted(ui._styles.items(),
459 460 key=lambda i: ('_' in i[0], i[0], i[1]))
460 461 for colorname, label in items:
461 462 ui.write(('%s\n') % colorname, label=label)
462 463
463 464 def _debugdisplaystyle(ui):
464 465 ui.write(_('available style:\n'))
465 466 if not ui._styles:
466 467 return
467 468 width = max(len(s) for s in ui._styles)
468 469 for label, effects in sorted(ui._styles.items()):
469 470 ui.write('%s' % label, label=label)
470 471 if effects:
471 472 # 50
472 473 ui.write(': ')
473 474 ui.write(' ' * (max(0, width - len(label))))
474 475 ui.write(', '.join(ui.label(e, e) for e in effects.split()))
475 476 ui.write('\n')
476 477
477 478 @command('debugcreatestreamclonebundle', [], 'FILE')
478 479 def debugcreatestreamclonebundle(ui, repo, fname):
479 480 """create a stream clone bundle file
480 481
481 482 Stream bundles are special bundles that are essentially archives of
482 483 revlog files. They are commonly used for cloning very quickly.
483 484 """
484 485 # TODO we may want to turn this into an abort when this functionality
485 486 # is moved into `hg bundle`.
486 487 if phases.hassecret(repo):
487 488 ui.warn(_('(warning: stream clone bundle will contain secret '
488 489 'revisions)\n'))
489 490
490 491 requirements, gen = streamclone.generatebundlev1(repo)
491 492 changegroup.writechunks(ui, gen, fname)
492 493
493 494 ui.write(_('bundle requirements: %s\n') % ', '.join(sorted(requirements)))
494 495
495 496 @command('debugdag',
496 497 [('t', 'tags', None, _('use tags as labels')),
497 498 ('b', 'branches', None, _('annotate with branch names')),
498 499 ('', 'dots', None, _('use dots for runs')),
499 500 ('s', 'spaces', None, _('separate elements by spaces'))],
500 501 _('[OPTION]... [FILE [REV]...]'),
501 502 optionalrepo=True)
502 503 def debugdag(ui, repo, file_=None, *revs, **opts):
503 504 """format the changelog or an index DAG as a concise textual description
504 505
505 506 If you pass a revlog index, the revlog's DAG is emitted. If you list
506 507 revision numbers, they get labeled in the output as rN.
507 508
508 509 Otherwise, the changelog DAG of the current repo is emitted.
509 510 """
510 511 spaces = opts.get(r'spaces')
511 512 dots = opts.get(r'dots')
512 513 if file_:
513 514 rlog = revlog.revlog(vfsmod.vfs(pycompat.getcwd(), audit=False),
514 515 file_)
515 516 revs = set((int(r) for r in revs))
516 517 def events():
517 518 for r in rlog:
518 519 yield 'n', (r, list(p for p in rlog.parentrevs(r)
519 520 if p != -1))
520 521 if r in revs:
521 522 yield 'l', (r, "r%i" % r)
522 523 elif repo:
523 524 cl = repo.changelog
524 525 tags = opts.get(r'tags')
525 526 branches = opts.get(r'branches')
526 527 if tags:
527 528 labels = {}
528 529 for l, n in repo.tags().items():
529 530 labels.setdefault(cl.rev(n), []).append(l)
530 531 def events():
531 532 b = "default"
532 533 for r in cl:
533 534 if branches:
534 535 newb = cl.read(cl.node(r))[5]['branch']
535 536 if newb != b:
536 537 yield 'a', newb
537 538 b = newb
538 539 yield 'n', (r, list(p for p in cl.parentrevs(r)
539 540 if p != -1))
540 541 if tags:
541 542 ls = labels.get(r)
542 543 if ls:
543 544 for l in ls:
544 545 yield 'l', (r, l)
545 546 else:
546 547 raise error.Abort(_('need repo for changelog dag'))
547 548
548 549 for line in dagparser.dagtextlines(events(),
549 550 addspaces=spaces,
550 551 wraplabels=True,
551 552 wrapannotations=True,
552 553 wrapnonlinear=dots,
553 554 usedots=dots,
554 555 maxlinewidth=70):
555 556 ui.write(line)
556 557 ui.write("\n")
557 558
558 559 @command('debugdata', cmdutil.debugrevlogopts, _('-c|-m|FILE REV'))
559 560 def debugdata(ui, repo, file_, rev=None, **opts):
560 561 """dump the contents of a data file revision"""
561 562 opts = pycompat.byteskwargs(opts)
562 563 if opts.get('changelog') or opts.get('manifest') or opts.get('dir'):
563 564 if rev is not None:
564 565 raise error.CommandError('debugdata', _('invalid arguments'))
565 566 file_, rev = None, file_
566 567 elif rev is None:
567 568 raise error.CommandError('debugdata', _('invalid arguments'))
568 569 r = cmdutil.openrevlog(repo, 'debugdata', file_, opts)
569 570 try:
570 571 ui.write(r.revision(r.lookup(rev), raw=True))
571 572 except KeyError:
572 573 raise error.Abort(_('invalid revision identifier %s') % rev)
573 574
574 575 @command('debugdate',
575 576 [('e', 'extended', None, _('try extended date formats'))],
576 577 _('[-e] DATE [RANGE]'),
577 578 norepo=True, optionalrepo=True)
578 579 def debugdate(ui, date, range=None, **opts):
579 580 """parse and display a date"""
580 581 if opts[r"extended"]:
581 582 d = dateutil.parsedate(date, util.extendeddateformats)
582 583 else:
583 584 d = dateutil.parsedate(date)
584 585 ui.write(("internal: %d %d\n") % d)
585 586 ui.write(("standard: %s\n") % dateutil.datestr(d))
586 587 if range:
587 588 m = dateutil.matchdate(range)
588 589 ui.write(("match: %s\n") % m(d[0]))
589 590
590 591 @command('debugdeltachain',
591 592 cmdutil.debugrevlogopts + cmdutil.formatteropts,
592 593 _('-c|-m|FILE'),
593 594 optionalrepo=True)
594 595 def debugdeltachain(ui, repo, file_=None, **opts):
595 596 """dump information about delta chains in a revlog
596 597
597 598 Output can be templatized. Available template keywords are:
598 599
599 600 :``rev``: revision number
600 601 :``chainid``: delta chain identifier (numbered by unique base)
601 602 :``chainlen``: delta chain length to this revision
602 603 :``prevrev``: previous revision in delta chain
603 604 :``deltatype``: role of delta / how it was computed
604 605 :``compsize``: compressed size of revision
605 606 :``uncompsize``: uncompressed size of revision
606 607 :``chainsize``: total size of compressed revisions in chain
607 608 :``chainratio``: total chain size divided by uncompressed revision size
608 609 (new delta chains typically start at ratio 2.00)
609 610 :``lindist``: linear distance from base revision in delta chain to end
610 611 of this revision
611 612 :``extradist``: total size of revisions not part of this delta chain from
612 613 base of delta chain to end of this revision; a measurement
613 614 of how much extra data we need to read/seek across to read
614 615 the delta chain for this revision
615 616 :``extraratio``: extradist divided by chainsize; another representation of
616 617 how much unrelated data is needed to load this delta chain
617 618
618 619 If the repository is configured to use the sparse read, additional keywords
619 620 are available:
620 621
621 622 :``readsize``: total size of data read from the disk for a revision
622 623 (sum of the sizes of all the blocks)
623 624 :``largestblock``: size of the largest block of data read from the disk
624 625 :``readdensity``: density of useful bytes in the data read from the disk
625 626 :``srchunks``: in how many data hunks the whole revision would be read
626 627
627 628 The sparse read can be enabled with experimental.sparse-read = True
628 629 """
629 630 opts = pycompat.byteskwargs(opts)
630 631 r = cmdutil.openrevlog(repo, 'debugdeltachain', file_, opts)
631 632 index = r.index
632 633 generaldelta = r.version & revlog.FLAG_GENERALDELTA
633 634 withsparseread = getattr(r, '_withsparseread', False)
634 635
635 636 def revinfo(rev):
636 637 e = index[rev]
637 638 compsize = e[1]
638 639 uncompsize = e[2]
639 640 chainsize = 0
640 641
641 642 if generaldelta:
642 643 if e[3] == e[5]:
643 644 deltatype = 'p1'
644 645 elif e[3] == e[6]:
645 646 deltatype = 'p2'
646 647 elif e[3] == rev - 1:
647 648 deltatype = 'prev'
648 649 elif e[3] == rev:
649 650 deltatype = 'base'
650 651 else:
651 652 deltatype = 'other'
652 653 else:
653 654 if e[3] == rev:
654 655 deltatype = 'base'
655 656 else:
656 657 deltatype = 'prev'
657 658
658 659 chain = r._deltachain(rev)[0]
659 660 for iterrev in chain:
660 661 e = index[iterrev]
661 662 chainsize += e[1]
662 663
663 664 return compsize, uncompsize, deltatype, chain, chainsize
664 665
665 666 fm = ui.formatter('debugdeltachain', opts)
666 667
667 668 fm.plain(' rev chain# chainlen prev delta '
668 669 'size rawsize chainsize ratio lindist extradist '
669 670 'extraratio')
670 671 if withsparseread:
671 672 fm.plain(' readsize largestblk rddensity srchunks')
672 673 fm.plain('\n')
673 674
674 675 chainbases = {}
675 676 for rev in r:
676 677 comp, uncomp, deltatype, chain, chainsize = revinfo(rev)
677 678 chainbase = chain[0]
678 679 chainid = chainbases.setdefault(chainbase, len(chainbases) + 1)
679 680 start = r.start
680 681 length = r.length
681 682 basestart = start(chainbase)
682 683 revstart = start(rev)
683 684 lineardist = revstart + comp - basestart
684 685 extradist = lineardist - chainsize
685 686 try:
686 687 prevrev = chain[-2]
687 688 except IndexError:
688 689 prevrev = -1
689 690
690 691 chainratio = float(chainsize) / float(uncomp)
691 692 extraratio = float(extradist) / float(chainsize)
692 693
693 694 fm.startitem()
694 695 fm.write('rev chainid chainlen prevrev deltatype compsize '
695 696 'uncompsize chainsize chainratio lindist extradist '
696 697 'extraratio',
697 698 '%7d %7d %8d %8d %7s %10d %10d %10d %9.5f %9d %9d %10.5f',
698 699 rev, chainid, len(chain), prevrev, deltatype, comp,
699 700 uncomp, chainsize, chainratio, lineardist, extradist,
700 701 extraratio,
701 702 rev=rev, chainid=chainid, chainlen=len(chain),
702 703 prevrev=prevrev, deltatype=deltatype, compsize=comp,
703 704 uncompsize=uncomp, chainsize=chainsize,
704 705 chainratio=chainratio, lindist=lineardist,
705 706 extradist=extradist, extraratio=extraratio)
706 707 if withsparseread:
707 708 readsize = 0
708 709 largestblock = 0
709 710 srchunks = 0
710 711
711 712 for revschunk in revlog._slicechunk(r, chain):
712 713 srchunks += 1
713 714 blkend = start(revschunk[-1]) + length(revschunk[-1])
714 715 blksize = blkend - start(revschunk[0])
715 716
716 717 readsize += blksize
717 718 if largestblock < blksize:
718 719 largestblock = blksize
719 720
720 721 readdensity = float(chainsize) / float(readsize)
721 722
722 723 fm.write('readsize largestblock readdensity srchunks',
723 724 ' %10d %10d %9.5f %8d',
724 725 readsize, largestblock, readdensity, srchunks,
725 726 readsize=readsize, largestblock=largestblock,
726 727 readdensity=readdensity, srchunks=srchunks)
727 728
728 729 fm.plain('\n')
729 730
730 731 fm.end()
731 732
732 733 @command('debugdirstate|debugstate',
733 734 [('', 'nodates', None, _('do not display the saved mtime')),
734 735 ('', 'datesort', None, _('sort by saved mtime'))],
735 736 _('[OPTION]...'))
736 737 def debugstate(ui, repo, **opts):
737 738 """show the contents of the current dirstate"""
738 739
739 740 nodates = opts.get(r'nodates')
740 741 datesort = opts.get(r'datesort')
741 742
742 743 timestr = ""
743 744 if datesort:
744 745 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
745 746 else:
746 747 keyfunc = None # sort by filename
747 748 for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
748 749 if ent[3] == -1:
749 750 timestr = 'unset '
750 751 elif nodates:
751 752 timestr = 'set '
752 753 else:
753 754 timestr = time.strftime(r"%Y-%m-%d %H:%M:%S ",
754 755 time.localtime(ent[3]))
755 756 timestr = encoding.strtolocal(timestr)
756 757 if ent[1] & 0o20000:
757 758 mode = 'lnk'
758 759 else:
759 760 mode = '%3o' % (ent[1] & 0o777 & ~util.umask)
760 761 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
761 762 for f in repo.dirstate.copies():
762 763 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
763 764
764 765 @command('debugdiscovery',
765 766 [('', 'old', None, _('use old-style discovery')),
766 767 ('', 'nonheads', None,
767 768 _('use old-style discovery with non-heads included')),
768 769 ('', 'rev', [], 'restrict discovery to this set of revs'),
769 770 ] + cmdutil.remoteopts,
770 771 _('[--rev REV] [OTHER]'))
771 772 def debugdiscovery(ui, repo, remoteurl="default", **opts):
772 773 """runs the changeset discovery protocol in isolation"""
773 774 opts = pycompat.byteskwargs(opts)
774 775 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl))
775 776 remote = hg.peer(repo, opts, remoteurl)
776 777 ui.status(_('comparing with %s\n') % util.hidepassword(remoteurl))
777 778
778 779 # make sure tests are repeatable
779 780 random.seed(12323)
780 781
781 782 def doit(pushedrevs, remoteheads, remote=remote):
782 783 if opts.get('old'):
783 784 if not util.safehasattr(remote, 'branches'):
784 785 # enable in-client legacy support
785 786 remote = localrepo.locallegacypeer(remote.local())
786 787 common, _in, hds = treediscovery.findcommonincoming(repo, remote,
787 788 force=True)
788 789 common = set(common)
789 790 if not opts.get('nonheads'):
790 791 ui.write(("unpruned common: %s\n") %
791 792 " ".join(sorted(short(n) for n in common)))
792 793 dag = dagutil.revlogdag(repo.changelog)
793 794 all = dag.ancestorset(dag.internalizeall(common))
794 795 common = dag.externalizeall(dag.headsetofconnecteds(all))
795 796 else:
796 797 nodes = None
797 798 if pushedrevs:
798 799 revs = scmutil.revrange(repo, pushedrevs)
799 800 nodes = [repo[r].node() for r in revs]
800 801 common, any, hds = setdiscovery.findcommonheads(ui, repo, remote,
801 802 ancestorsof=nodes)
802 803 common = set(common)
803 804 rheads = set(hds)
804 805 lheads = set(repo.heads())
805 806 ui.write(("common heads: %s\n") %
806 807 " ".join(sorted(short(n) for n in common)))
807 808 if lheads <= common:
808 809 ui.write(("local is subset\n"))
809 810 elif rheads <= common:
810 811 ui.write(("remote is subset\n"))
811 812
812 813 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches, revs=None)
813 814 localrevs = opts['rev']
814 815 doit(localrevs, remoterevs)
815 816
816 817 _chunksize = 4 << 10
817 818
818 819 @command('debugdownload',
819 820 [
820 821 ('o', 'output', '', _('path')),
821 822 ],
822 823 optionalrepo=True)
823 824 def debugdownload(ui, repo, url, output=None, **opts):
824 825 """download a resource using Mercurial logic and config
825 826 """
826 827 fh = urlmod.open(ui, url, output)
827 828
828 829 dest = ui
829 830 if output:
830 831 dest = open(output, "wb", _chunksize)
831 832 try:
832 833 data = fh.read(_chunksize)
833 834 while data:
834 835 dest.write(data)
835 836 data = fh.read(_chunksize)
836 837 finally:
837 838 if output:
838 839 dest.close()
839 840
840 841 @command('debugextensions', cmdutil.formatteropts, [], norepo=True)
841 842 def debugextensions(ui, **opts):
842 843 '''show information about active extensions'''
843 844 opts = pycompat.byteskwargs(opts)
844 845 exts = extensions.extensions(ui)
845 846 hgver = util.version()
846 847 fm = ui.formatter('debugextensions', opts)
847 848 for extname, extmod in sorted(exts, key=operator.itemgetter(0)):
848 849 isinternal = extensions.ismoduleinternal(extmod)
849 850 extsource = pycompat.fsencode(extmod.__file__)
850 851 if isinternal:
851 852 exttestedwith = [] # never expose magic string to users
852 853 else:
853 854 exttestedwith = getattr(extmod, 'testedwith', '').split()
854 855 extbuglink = getattr(extmod, 'buglink', None)
855 856
856 857 fm.startitem()
857 858
858 859 if ui.quiet or ui.verbose:
859 860 fm.write('name', '%s\n', extname)
860 861 else:
861 862 fm.write('name', '%s', extname)
862 863 if isinternal or hgver in exttestedwith:
863 864 fm.plain('\n')
864 865 elif not exttestedwith:
865 866 fm.plain(_(' (untested!)\n'))
866 867 else:
867 868 lasttestedversion = exttestedwith[-1]
868 869 fm.plain(' (%s!)\n' % lasttestedversion)
869 870
870 871 fm.condwrite(ui.verbose and extsource, 'source',
871 872 _(' location: %s\n'), extsource or "")
872 873
873 874 if ui.verbose:
874 875 fm.plain(_(' bundled: %s\n') % ['no', 'yes'][isinternal])
875 876 fm.data(bundled=isinternal)
876 877
877 878 fm.condwrite(ui.verbose and exttestedwith, 'testedwith',
878 879 _(' tested with: %s\n'),
879 880 fm.formatlist(exttestedwith, name='ver'))
880 881
881 882 fm.condwrite(ui.verbose and extbuglink, 'buglink',
882 883 _(' bug reporting: %s\n'), extbuglink or "")
883 884
884 885 fm.end()
885 886
886 887 @command('debugfileset',
887 888 [('r', 'rev', '', _('apply the filespec on this revision'), _('REV'))],
888 889 _('[-r REV] FILESPEC'))
889 890 def debugfileset(ui, repo, expr, **opts):
890 891 '''parse and apply a fileset specification'''
891 892 ctx = scmutil.revsingle(repo, opts.get(r'rev'), None)
892 893 if ui.verbose:
893 894 tree = fileset.parse(expr)
894 895 ui.note(fileset.prettyformat(tree), "\n")
895 896
896 897 for f in ctx.getfileset(expr):
897 898 ui.write("%s\n" % f)
898 899
899 900 @command('debugformat',
900 901 [] + cmdutil.formatteropts,
901 902 _(''))
902 903 def debugformat(ui, repo, **opts):
903 904 """display format information about the current repository
904 905
905 906 Use --verbose to get extra information about current config value and
906 907 Mercurial default."""
907 908 opts = pycompat.byteskwargs(opts)
908 909 maxvariantlength = max(len(fv.name) for fv in upgrade.allformatvariant)
909 910 maxvariantlength = max(len('format-variant'), maxvariantlength)
910 911
911 912 def makeformatname(name):
912 913 return '%s:' + (' ' * (maxvariantlength - len(name)))
913 914
914 915 fm = ui.formatter('debugformat', opts)
915 916 if fm.isplain():
916 917 def formatvalue(value):
917 918 if util.safehasattr(value, 'startswith'):
918 919 return value
919 920 if value:
920 921 return 'yes'
921 922 else:
922 923 return 'no'
923 924 else:
924 925 formatvalue = pycompat.identity
925 926
926 927 fm.plain('format-variant')
927 928 fm.plain(' ' * (maxvariantlength - len('format-variant')))
928 929 fm.plain(' repo')
929 930 if ui.verbose:
930 931 fm.plain(' config default')
931 932 fm.plain('\n')
932 933 for fv in upgrade.allformatvariant:
933 934 fm.startitem()
934 935 repovalue = fv.fromrepo(repo)
935 936 configvalue = fv.fromconfig(repo)
936 937
937 938 if repovalue != configvalue:
938 939 namelabel = 'formatvariant.name.mismatchconfig'
939 940 repolabel = 'formatvariant.repo.mismatchconfig'
940 941 elif repovalue != fv.default:
941 942 namelabel = 'formatvariant.name.mismatchdefault'
942 943 repolabel = 'formatvariant.repo.mismatchdefault'
943 944 else:
944 945 namelabel = 'formatvariant.name.uptodate'
945 946 repolabel = 'formatvariant.repo.uptodate'
946 947
947 948 fm.write('name', makeformatname(fv.name), fv.name,
948 949 label=namelabel)
949 950 fm.write('repo', ' %3s', formatvalue(repovalue),
950 951 label=repolabel)
951 952 if fv.default != configvalue:
952 953 configlabel = 'formatvariant.config.special'
953 954 else:
954 955 configlabel = 'formatvariant.config.default'
955 956 fm.condwrite(ui.verbose, 'config', ' %6s', formatvalue(configvalue),
956 957 label=configlabel)
957 958 fm.condwrite(ui.verbose, 'default', ' %7s', formatvalue(fv.default),
958 959 label='formatvariant.default')
959 960 fm.plain('\n')
960 961 fm.end()
961 962
962 963 @command('debugfsinfo', [], _('[PATH]'), norepo=True)
963 964 def debugfsinfo(ui, path="."):
964 965 """show information detected about current filesystem"""
965 966 ui.write(('path: %s\n') % path)
966 967 ui.write(('mounted on: %s\n') % (util.getfsmountpoint(path) or '(unknown)'))
967 968 ui.write(('exec: %s\n') % (util.checkexec(path) and 'yes' or 'no'))
968 969 ui.write(('fstype: %s\n') % (util.getfstype(path) or '(unknown)'))
969 970 ui.write(('symlink: %s\n') % (util.checklink(path) and 'yes' or 'no'))
970 971 ui.write(('hardlink: %s\n') % (util.checknlink(path) and 'yes' or 'no'))
971 972 casesensitive = '(unknown)'
972 973 try:
973 974 with tempfile.NamedTemporaryFile(prefix='.debugfsinfo', dir=path) as f:
974 975 casesensitive = util.fscasesensitive(f.name) and 'yes' or 'no'
975 976 except OSError:
976 977 pass
977 978 ui.write(('case-sensitive: %s\n') % casesensitive)
978 979
979 980 @command('debuggetbundle',
980 981 [('H', 'head', [], _('id of head node'), _('ID')),
981 982 ('C', 'common', [], _('id of common node'), _('ID')),
982 983 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE'))],
983 984 _('REPO FILE [-H|-C ID]...'),
984 985 norepo=True)
985 986 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
986 987 """retrieves a bundle from a repo
987 988
988 989 Every ID must be a full-length hex node id string. Saves the bundle to the
989 990 given file.
990 991 """
991 992 opts = pycompat.byteskwargs(opts)
992 993 repo = hg.peer(ui, opts, repopath)
993 994 if not repo.capable('getbundle'):
994 995 raise error.Abort("getbundle() not supported by target repository")
995 996 args = {}
996 997 if common:
997 998 args[r'common'] = [bin(s) for s in common]
998 999 if head:
999 1000 args[r'heads'] = [bin(s) for s in head]
1000 1001 # TODO: get desired bundlecaps from command line.
1001 1002 args[r'bundlecaps'] = None
1002 1003 bundle = repo.getbundle('debug', **args)
1003 1004
1004 1005 bundletype = opts.get('type', 'bzip2').lower()
1005 1006 btypes = {'none': 'HG10UN',
1006 1007 'bzip2': 'HG10BZ',
1007 1008 'gzip': 'HG10GZ',
1008 1009 'bundle2': 'HG20'}
1009 1010 bundletype = btypes.get(bundletype)
1010 1011 if bundletype not in bundle2.bundletypes:
1011 1012 raise error.Abort(_('unknown bundle type specified with --type'))
1012 1013 bundle2.writebundle(ui, bundle, bundlepath, bundletype)
1013 1014
1014 1015 @command('debugignore', [], '[FILE]')
1015 1016 def debugignore(ui, repo, *files, **opts):
1016 1017 """display the combined ignore pattern and information about ignored files
1017 1018
1018 1019 With no argument display the combined ignore pattern.
1019 1020
1020 1021 Given space separated file names, shows if the given file is ignored and
1021 1022 if so, show the ignore rule (file and line number) that matched it.
1022 1023 """
1023 1024 ignore = repo.dirstate._ignore
1024 1025 if not files:
1025 1026 # Show all the patterns
1026 1027 ui.write("%s\n" % pycompat.byterepr(ignore))
1027 1028 else:
1028 1029 m = scmutil.match(repo[None], pats=files)
1029 1030 for f in m.files():
1030 1031 nf = util.normpath(f)
1031 1032 ignored = None
1032 1033 ignoredata = None
1033 1034 if nf != '.':
1034 1035 if ignore(nf):
1035 1036 ignored = nf
1036 1037 ignoredata = repo.dirstate._ignorefileandline(nf)
1037 1038 else:
1038 1039 for p in util.finddirs(nf):
1039 1040 if ignore(p):
1040 1041 ignored = p
1041 1042 ignoredata = repo.dirstate._ignorefileandline(p)
1042 1043 break
1043 1044 if ignored:
1044 1045 if ignored == nf:
1045 1046 ui.write(_("%s is ignored\n") % m.uipath(f))
1046 1047 else:
1047 1048 ui.write(_("%s is ignored because of "
1048 1049 "containing folder %s\n")
1049 1050 % (m.uipath(f), ignored))
1050 1051 ignorefile, lineno, line = ignoredata
1051 1052 ui.write(_("(ignore rule in %s, line %d: '%s')\n")
1052 1053 % (ignorefile, lineno, line))
1053 1054 else:
1054 1055 ui.write(_("%s is not ignored\n") % m.uipath(f))
1055 1056
1056 1057 @command('debugindex', cmdutil.debugrevlogopts +
1057 1058 [('f', 'format', 0, _('revlog format'), _('FORMAT'))],
1058 1059 _('[-f FORMAT] -c|-m|FILE'),
1059 1060 optionalrepo=True)
1060 1061 def debugindex(ui, repo, file_=None, **opts):
1061 1062 """dump the contents of an index file"""
1062 1063 opts = pycompat.byteskwargs(opts)
1063 1064 r = cmdutil.openrevlog(repo, 'debugindex', file_, opts)
1064 1065 format = opts.get('format', 0)
1065 1066 if format not in (0, 1):
1066 1067 raise error.Abort(_("unknown format %d") % format)
1067 1068
1068 1069 if ui.debugflag:
1069 1070 shortfn = hex
1070 1071 else:
1071 1072 shortfn = short
1072 1073
1073 1074 # There might not be anything in r, so have a sane default
1074 1075 idlen = 12
1075 1076 for i in r:
1076 1077 idlen = len(shortfn(r.node(i)))
1077 1078 break
1078 1079
1079 1080 if format == 0:
1080 1081 if ui.verbose:
1081 1082 ui.write((" rev offset length linkrev"
1082 1083 " %s %s p2\n") % ("nodeid".ljust(idlen),
1083 1084 "p1".ljust(idlen)))
1084 1085 else:
1085 1086 ui.write((" rev linkrev %s %s p2\n") % (
1086 1087 "nodeid".ljust(idlen), "p1".ljust(idlen)))
1087 1088 elif format == 1:
1088 1089 if ui.verbose:
1089 1090 ui.write((" rev flag offset length size link p1"
1090 1091 " p2 %s\n") % "nodeid".rjust(idlen))
1091 1092 else:
1092 1093 ui.write((" rev flag size link p1 p2 %s\n") %
1093 1094 "nodeid".rjust(idlen))
1094 1095
1095 1096 for i in r:
1096 1097 node = r.node(i)
1097 1098 if format == 0:
1098 1099 try:
1099 1100 pp = r.parents(node)
1100 1101 except Exception:
1101 1102 pp = [nullid, nullid]
1102 1103 if ui.verbose:
1103 1104 ui.write("% 6d % 9d % 7d % 7d %s %s %s\n" % (
1104 1105 i, r.start(i), r.length(i), r.linkrev(i),
1105 1106 shortfn(node), shortfn(pp[0]), shortfn(pp[1])))
1106 1107 else:
1107 1108 ui.write("% 6d % 7d %s %s %s\n" % (
1108 1109 i, r.linkrev(i), shortfn(node), shortfn(pp[0]),
1109 1110 shortfn(pp[1])))
1110 1111 elif format == 1:
1111 1112 pr = r.parentrevs(i)
1112 1113 if ui.verbose:
1113 1114 ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d %s\n" % (
1114 1115 i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
1115 1116 r.linkrev(i), pr[0], pr[1], shortfn(node)))
1116 1117 else:
1117 1118 ui.write("% 6d %04x % 8d % 6d % 6d % 6d %s\n" % (
1118 1119 i, r.flags(i), r.rawsize(i), r.linkrev(i), pr[0], pr[1],
1119 1120 shortfn(node)))
1120 1121
1121 1122 @command('debugindexdot', cmdutil.debugrevlogopts,
1122 1123 _('-c|-m|FILE'), optionalrepo=True)
1123 1124 def debugindexdot(ui, repo, file_=None, **opts):
1124 1125 """dump an index DAG as a graphviz dot file"""
1125 1126 opts = pycompat.byteskwargs(opts)
1126 1127 r = cmdutil.openrevlog(repo, 'debugindexdot', file_, opts)
1127 1128 ui.write(("digraph G {\n"))
1128 1129 for i in r:
1129 1130 node = r.node(i)
1130 1131 pp = r.parents(node)
1131 1132 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
1132 1133 if pp[1] != nullid:
1133 1134 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
1134 1135 ui.write("}\n")
1135 1136
1136 1137 @command('debuginstall', [] + cmdutil.formatteropts, '', norepo=True)
1137 1138 def debuginstall(ui, **opts):
1138 1139 '''test Mercurial installation
1139 1140
1140 1141 Returns 0 on success.
1141 1142 '''
1142 1143 opts = pycompat.byteskwargs(opts)
1143 1144
1144 1145 def writetemp(contents):
1145 1146 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
1146 1147 f = os.fdopen(fd, r"wb")
1147 1148 f.write(contents)
1148 1149 f.close()
1149 1150 return name
1150 1151
1151 1152 problems = 0
1152 1153
1153 1154 fm = ui.formatter('debuginstall', opts)
1154 1155 fm.startitem()
1155 1156
1156 1157 # encoding
1157 1158 fm.write('encoding', _("checking encoding (%s)...\n"), encoding.encoding)
1158 1159 err = None
1159 1160 try:
1160 1161 codecs.lookup(pycompat.sysstr(encoding.encoding))
1161 1162 except LookupError as inst:
1162 1163 err = stringutil.forcebytestr(inst)
1163 1164 problems += 1
1164 1165 fm.condwrite(err, 'encodingerror', _(" %s\n"
1165 1166 " (check that your locale is properly set)\n"), err)
1166 1167
1167 1168 # Python
1168 1169 fm.write('pythonexe', _("checking Python executable (%s)\n"),
1169 1170 pycompat.sysexecutable)
1170 1171 fm.write('pythonver', _("checking Python version (%s)\n"),
1171 1172 ("%d.%d.%d" % sys.version_info[:3]))
1172 1173 fm.write('pythonlib', _("checking Python lib (%s)...\n"),
1173 1174 os.path.dirname(pycompat.fsencode(os.__file__)))
1174 1175
1175 1176 security = set(sslutil.supportedprotocols)
1176 1177 if sslutil.hassni:
1177 1178 security.add('sni')
1178 1179
1179 1180 fm.write('pythonsecurity', _("checking Python security support (%s)\n"),
1180 1181 fm.formatlist(sorted(security), name='protocol',
1181 1182 fmt='%s', sep=','))
1182 1183
1183 1184 # These are warnings, not errors. So don't increment problem count. This
1184 1185 # may change in the future.
1185 1186 if 'tls1.2' not in security:
1186 1187 fm.plain(_(' TLS 1.2 not supported by Python install; '
1187 1188 'network connections lack modern security\n'))
1188 1189 if 'sni' not in security:
1189 1190 fm.plain(_(' SNI not supported by Python install; may have '
1190 1191 'connectivity issues with some servers\n'))
1191 1192
1192 1193 # TODO print CA cert info
1193 1194
1194 1195 # hg version
1195 1196 hgver = util.version()
1196 1197 fm.write('hgver', _("checking Mercurial version (%s)\n"),
1197 1198 hgver.split('+')[0])
1198 1199 fm.write('hgverextra', _("checking Mercurial custom build (%s)\n"),
1199 1200 '+'.join(hgver.split('+')[1:]))
1200 1201
1201 1202 # compiled modules
1202 1203 fm.write('hgmodulepolicy', _("checking module policy (%s)\n"),
1203 1204 policy.policy)
1204 1205 fm.write('hgmodules', _("checking installed modules (%s)...\n"),
1205 1206 os.path.dirname(pycompat.fsencode(__file__)))
1206 1207
1207 1208 if policy.policy in ('c', 'allow'):
1208 1209 err = None
1209 1210 try:
1210 1211 from .cext import (
1211 1212 base85,
1212 1213 bdiff,
1213 1214 mpatch,
1214 1215 osutil,
1215 1216 )
1216 1217 dir(bdiff), dir(mpatch), dir(base85), dir(osutil) # quiet pyflakes
1217 1218 except Exception as inst:
1218 1219 err = stringutil.forcebytestr(inst)
1219 1220 problems += 1
1220 1221 fm.condwrite(err, 'extensionserror', " %s\n", err)
1221 1222
1222 1223 compengines = util.compengines._engines.values()
1223 1224 fm.write('compengines', _('checking registered compression engines (%s)\n'),
1224 1225 fm.formatlist(sorted(e.name() for e in compengines),
1225 1226 name='compengine', fmt='%s', sep=', '))
1226 1227 fm.write('compenginesavail', _('checking available compression engines '
1227 1228 '(%s)\n'),
1228 1229 fm.formatlist(sorted(e.name() for e in compengines
1229 1230 if e.available()),
1230 1231 name='compengine', fmt='%s', sep=', '))
1231 1232 wirecompengines = util.compengines.supportedwireengines(util.SERVERROLE)
1232 1233 fm.write('compenginesserver', _('checking available compression engines '
1233 1234 'for wire protocol (%s)\n'),
1234 1235 fm.formatlist([e.name() for e in wirecompengines
1235 1236 if e.wireprotosupport()],
1236 1237 name='compengine', fmt='%s', sep=', '))
1237 1238 re2 = 'missing'
1238 1239 if util._re2:
1239 1240 re2 = 'available'
1240 1241 fm.plain(_('checking "re2" regexp engine (%s)\n') % re2)
1241 1242 fm.data(re2=bool(util._re2))
1242 1243
1243 1244 # templates
1244 1245 p = templater.templatepaths()
1245 1246 fm.write('templatedirs', 'checking templates (%s)...\n', ' '.join(p))
1246 1247 fm.condwrite(not p, '', _(" no template directories found\n"))
1247 1248 if p:
1248 1249 m = templater.templatepath("map-cmdline.default")
1249 1250 if m:
1250 1251 # template found, check if it is working
1251 1252 err = None
1252 1253 try:
1253 1254 templater.templater.frommapfile(m)
1254 1255 except Exception as inst:
1255 1256 err = stringutil.forcebytestr(inst)
1256 1257 p = None
1257 1258 fm.condwrite(err, 'defaulttemplateerror', " %s\n", err)
1258 1259 else:
1259 1260 p = None
1260 1261 fm.condwrite(p, 'defaulttemplate',
1261 1262 _("checking default template (%s)\n"), m)
1262 1263 fm.condwrite(not m, 'defaulttemplatenotfound',
1263 1264 _(" template '%s' not found\n"), "default")
1264 1265 if not p:
1265 1266 problems += 1
1266 1267 fm.condwrite(not p, '',
1267 1268 _(" (templates seem to have been installed incorrectly)\n"))
1268 1269
1269 1270 # editor
1270 1271 editor = ui.geteditor()
1271 1272 editor = util.expandpath(editor)
1272 1273 editorbin = procutil.shellsplit(editor)[0]
1273 1274 fm.write('editor', _("checking commit editor... (%s)\n"), editorbin)
1274 1275 cmdpath = procutil.findexe(editorbin)
1275 1276 fm.condwrite(not cmdpath and editor == 'vi', 'vinotfound',
1276 1277 _(" No commit editor set and can't find %s in PATH\n"
1277 1278 " (specify a commit editor in your configuration"
1278 1279 " file)\n"), not cmdpath and editor == 'vi' and editorbin)
1279 1280 fm.condwrite(not cmdpath and editor != 'vi', 'editornotfound',
1280 1281 _(" Can't find editor '%s' in PATH\n"
1281 1282 " (specify a commit editor in your configuration"
1282 1283 " file)\n"), not cmdpath and editorbin)
1283 1284 if not cmdpath and editor != 'vi':
1284 1285 problems += 1
1285 1286
1286 1287 # check username
1287 1288 username = None
1288 1289 err = None
1289 1290 try:
1290 1291 username = ui.username()
1291 1292 except error.Abort as e:
1292 1293 err = stringutil.forcebytestr(e)
1293 1294 problems += 1
1294 1295
1295 1296 fm.condwrite(username, 'username', _("checking username (%s)\n"), username)
1296 1297 fm.condwrite(err, 'usernameerror', _("checking username...\n %s\n"
1297 1298 " (specify a username in your configuration file)\n"), err)
1298 1299
1299 1300 fm.condwrite(not problems, '',
1300 1301 _("no problems detected\n"))
1301 1302 if not problems:
1302 1303 fm.data(problems=problems)
1303 1304 fm.condwrite(problems, 'problems',
1304 1305 _("%d problems detected,"
1305 1306 " please check your install!\n"), problems)
1306 1307 fm.end()
1307 1308
1308 1309 return problems
1309 1310
1310 1311 @command('debugknown', [], _('REPO ID...'), norepo=True)
1311 1312 def debugknown(ui, repopath, *ids, **opts):
1312 1313 """test whether node ids are known to a repo
1313 1314
1314 1315 Every ID must be a full-length hex node id string. Returns a list of 0s
1315 1316 and 1s indicating unknown/known.
1316 1317 """
1317 1318 opts = pycompat.byteskwargs(opts)
1318 1319 repo = hg.peer(ui, opts, repopath)
1319 1320 if not repo.capable('known'):
1320 1321 raise error.Abort("known() not supported by target repository")
1321 1322 flags = repo.known([bin(s) for s in ids])
1322 1323 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
1323 1324
1324 1325 @command('debuglabelcomplete', [], _('LABEL...'))
1325 1326 def debuglabelcomplete(ui, repo, *args):
1326 1327 '''backwards compatibility with old bash completion scripts (DEPRECATED)'''
1327 1328 debugnamecomplete(ui, repo, *args)
1328 1329
1329 1330 @command('debuglocks',
1330 1331 [('L', 'force-lock', None, _('free the store lock (DANGEROUS)')),
1331 1332 ('W', 'force-wlock', None,
1332 1333 _('free the working state lock (DANGEROUS)')),
1333 1334 ('s', 'set-lock', None, _('set the store lock until stopped')),
1334 1335 ('S', 'set-wlock', None,
1335 1336 _('set the working state lock until stopped'))],
1336 1337 _('[OPTION]...'))
1337 1338 def debuglocks(ui, repo, **opts):
1338 1339 """show or modify state of locks
1339 1340
1340 1341 By default, this command will show which locks are held. This
1341 1342 includes the user and process holding the lock, the amount of time
1342 1343 the lock has been held, and the machine name where the process is
1343 1344 running if it's not local.
1344 1345
1345 1346 Locks protect the integrity of Mercurial's data, so should be
1346 1347 treated with care. System crashes or other interruptions may cause
1347 1348 locks to not be properly released, though Mercurial will usually
1348 1349 detect and remove such stale locks automatically.
1349 1350
1350 1351 However, detecting stale locks may not always be possible (for
1351 1352 instance, on a shared filesystem). Removing locks may also be
1352 1353 blocked by filesystem permissions.
1353 1354
1354 1355 Setting a lock will prevent other commands from changing the data.
1355 1356 The command will wait until an interruption (SIGINT, SIGTERM, ...) occurs.
1356 1357 The set locks are removed when the command exits.
1357 1358
1358 1359 Returns 0 if no locks are held.
1359 1360
1360 1361 """
1361 1362
1362 1363 if opts.get(r'force_lock'):
1363 1364 repo.svfs.unlink('lock')
1364 1365 if opts.get(r'force_wlock'):
1365 1366 repo.vfs.unlink('wlock')
1366 1367 if opts.get(r'force_lock') or opts.get(r'force_wlock'):
1367 1368 return 0
1368 1369
1369 1370 locks = []
1370 1371 try:
1371 1372 if opts.get(r'set_wlock'):
1372 1373 try:
1373 1374 locks.append(repo.wlock(False))
1374 1375 except error.LockHeld:
1375 1376 raise error.Abort(_('wlock is already held'))
1376 1377 if opts.get(r'set_lock'):
1377 1378 try:
1378 1379 locks.append(repo.lock(False))
1379 1380 except error.LockHeld:
1380 1381 raise error.Abort(_('lock is already held'))
1381 1382 if len(locks):
1382 1383 ui.promptchoice(_("ready to release the lock (y)? $$ &Yes"))
1383 1384 return 0
1384 1385 finally:
1385 1386 release(*locks)
1386 1387
1387 1388 now = time.time()
1388 1389 held = 0
1389 1390
1390 1391 def report(vfs, name, method):
1391 1392 # this causes stale locks to get reaped for more accurate reporting
1392 1393 try:
1393 1394 l = method(False)
1394 1395 except error.LockHeld:
1395 1396 l = None
1396 1397
1397 1398 if l:
1398 1399 l.release()
1399 1400 else:
1400 1401 try:
1401 1402 st = vfs.lstat(name)
1402 1403 age = now - st[stat.ST_MTIME]
1403 1404 user = util.username(st.st_uid)
1404 1405 locker = vfs.readlock(name)
1405 1406 if ":" in locker:
1406 1407 host, pid = locker.split(':')
1407 1408 if host == socket.gethostname():
1408 1409 locker = 'user %s, process %s' % (user, pid)
1409 1410 else:
1410 1411 locker = 'user %s, process %s, host %s' \
1411 1412 % (user, pid, host)
1412 1413 ui.write(("%-6s %s (%ds)\n") % (name + ":", locker, age))
1413 1414 return 1
1414 1415 except OSError as e:
1415 1416 if e.errno != errno.ENOENT:
1416 1417 raise
1417 1418
1418 1419 ui.write(("%-6s free\n") % (name + ":"))
1419 1420 return 0
1420 1421
1421 1422 held += report(repo.svfs, "lock", repo.lock)
1422 1423 held += report(repo.vfs, "wlock", repo.wlock)
1423 1424
1424 1425 return held
1425 1426
1426 1427 @command('debugmergestate', [], '')
1427 1428 def debugmergestate(ui, repo, *args):
1428 1429 """print merge state
1429 1430
1430 1431 Use --verbose to print out information about whether v1 or v2 merge state
1431 1432 was chosen."""
1432 1433 def _hashornull(h):
1433 1434 if h == nullhex:
1434 1435 return 'null'
1435 1436 else:
1436 1437 return h
1437 1438
1438 1439 def printrecords(version):
1439 1440 ui.write(('* version %d records\n') % version)
1440 1441 if version == 1:
1441 1442 records = v1records
1442 1443 else:
1443 1444 records = v2records
1444 1445
1445 1446 for rtype, record in records:
1446 1447 # pretty print some record types
1447 1448 if rtype == 'L':
1448 1449 ui.write(('local: %s\n') % record)
1449 1450 elif rtype == 'O':
1450 1451 ui.write(('other: %s\n') % record)
1451 1452 elif rtype == 'm':
1452 1453 driver, mdstate = record.split('\0', 1)
1453 1454 ui.write(('merge driver: %s (state "%s")\n')
1454 1455 % (driver, mdstate))
1455 1456 elif rtype in 'FDC':
1456 1457 r = record.split('\0')
1457 1458 f, state, hash, lfile, afile, anode, ofile = r[0:7]
1458 1459 if version == 1:
1459 1460 onode = 'not stored in v1 format'
1460 1461 flags = r[7]
1461 1462 else:
1462 1463 onode, flags = r[7:9]
1463 1464 ui.write(('file: %s (record type "%s", state "%s", hash %s)\n')
1464 1465 % (f, rtype, state, _hashornull(hash)))
1465 1466 ui.write((' local path: %s (flags "%s")\n') % (lfile, flags))
1466 1467 ui.write((' ancestor path: %s (node %s)\n')
1467 1468 % (afile, _hashornull(anode)))
1468 1469 ui.write((' other path: %s (node %s)\n')
1469 1470 % (ofile, _hashornull(onode)))
1470 1471 elif rtype == 'f':
1471 1472 filename, rawextras = record.split('\0', 1)
1472 1473 extras = rawextras.split('\0')
1473 1474 i = 0
1474 1475 extrastrings = []
1475 1476 while i < len(extras):
1476 1477 extrastrings.append('%s = %s' % (extras[i], extras[i + 1]))
1477 1478 i += 2
1478 1479
1479 1480 ui.write(('file extras: %s (%s)\n')
1480 1481 % (filename, ', '.join(extrastrings)))
1481 1482 elif rtype == 'l':
1482 1483 labels = record.split('\0', 2)
1483 1484 labels = [l for l in labels if len(l) > 0]
1484 1485 ui.write(('labels:\n'))
1485 1486 ui.write((' local: %s\n' % labels[0]))
1486 1487 ui.write((' other: %s\n' % labels[1]))
1487 1488 if len(labels) > 2:
1488 1489 ui.write((' base: %s\n' % labels[2]))
1489 1490 else:
1490 1491 ui.write(('unrecognized entry: %s\t%s\n')
1491 1492 % (rtype, record.replace('\0', '\t')))
1492 1493
1493 1494 # Avoid mergestate.read() since it may raise an exception for unsupported
1494 1495 # merge state records. We shouldn't be doing this, but this is OK since this
1495 1496 # command is pretty low-level.
1496 1497 ms = mergemod.mergestate(repo)
1497 1498
1498 1499 # sort so that reasonable information is on top
1499 1500 v1records = ms._readrecordsv1()
1500 1501 v2records = ms._readrecordsv2()
1501 1502 order = 'LOml'
1502 1503 def key(r):
1503 1504 idx = order.find(r[0])
1504 1505 if idx == -1:
1505 1506 return (1, r[1])
1506 1507 else:
1507 1508 return (0, idx)
1508 1509 v1records.sort(key=key)
1509 1510 v2records.sort(key=key)
1510 1511
1511 1512 if not v1records and not v2records:
1512 1513 ui.write(('no merge state found\n'))
1513 1514 elif not v2records:
1514 1515 ui.note(('no version 2 merge state\n'))
1515 1516 printrecords(1)
1516 1517 elif ms._v1v2match(v1records, v2records):
1517 1518 ui.note(('v1 and v2 states match: using v2\n'))
1518 1519 printrecords(2)
1519 1520 else:
1520 1521 ui.note(('v1 and v2 states mismatch: using v1\n'))
1521 1522 printrecords(1)
1522 1523 if ui.verbose:
1523 1524 printrecords(2)
1524 1525
1525 1526 @command('debugnamecomplete', [], _('NAME...'))
1526 1527 def debugnamecomplete(ui, repo, *args):
1527 1528 '''complete "names" - tags, open branch names, bookmark names'''
1528 1529
1529 1530 names = set()
1530 1531 # since we previously only listed open branches, we will handle that
1531 1532 # specially (after this for loop)
1532 1533 for name, ns in repo.names.iteritems():
1533 1534 if name != 'branches':
1534 1535 names.update(ns.listnames(repo))
1535 1536 names.update(tag for (tag, heads, tip, closed)
1536 1537 in repo.branchmap().iterbranches() if not closed)
1537 1538 completions = set()
1538 1539 if not args:
1539 1540 args = ['']
1540 1541 for a in args:
1541 1542 completions.update(n for n in names if n.startswith(a))
1542 1543 ui.write('\n'.join(sorted(completions)))
1543 1544 ui.write('\n')
1544 1545
1545 1546 @command('debugobsolete',
1546 1547 [('', 'flags', 0, _('markers flag')),
1547 1548 ('', 'record-parents', False,
1548 1549 _('record parent information for the precursor')),
1549 1550 ('r', 'rev', [], _('display markers relevant to REV')),
1550 1551 ('', 'exclusive', False, _('restrict display to markers only '
1551 1552 'relevant to REV')),
1552 1553 ('', 'index', False, _('display index of the marker')),
1553 1554 ('', 'delete', [], _('delete markers specified by indices')),
1554 1555 ] + cmdutil.commitopts2 + cmdutil.formatteropts,
1555 1556 _('[OBSOLETED [REPLACEMENT ...]]'))
1556 1557 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
1557 1558 """create arbitrary obsolete marker
1558 1559
1559 1560 With no arguments, displays the list of obsolescence markers."""
1560 1561
1561 1562 opts = pycompat.byteskwargs(opts)
1562 1563
1563 1564 def parsenodeid(s):
1564 1565 try:
1565 1566 # We do not use revsingle/revrange functions here to accept
1566 1567 # arbitrary node identifiers, possibly not present in the
1567 1568 # local repository.
1568 1569 n = bin(s)
1569 1570 if len(n) != len(nullid):
1570 1571 raise TypeError()
1571 1572 return n
1572 1573 except TypeError:
1573 1574 raise error.Abort('changeset references must be full hexadecimal '
1574 1575 'node identifiers')
1575 1576
1576 1577 if opts.get('delete'):
1577 1578 indices = []
1578 1579 for v in opts.get('delete'):
1579 1580 try:
1580 1581 indices.append(int(v))
1581 1582 except ValueError:
1582 1583 raise error.Abort(_('invalid index value: %r') % v,
1583 1584 hint=_('use integers for indices'))
1584 1585
1585 1586 if repo.currenttransaction():
1586 1587 raise error.Abort(_('cannot delete obsmarkers in the middle '
1587 1588 'of transaction.'))
1588 1589
1589 1590 with repo.lock():
1590 1591 n = repair.deleteobsmarkers(repo.obsstore, indices)
1591 1592 ui.write(_('deleted %i obsolescence markers\n') % n)
1592 1593
1593 1594 return
1594 1595
1595 1596 if precursor is not None:
1596 1597 if opts['rev']:
1597 1598 raise error.Abort('cannot select revision when creating marker')
1598 1599 metadata = {}
1599 1600 metadata['user'] = opts['user'] or ui.username()
1600 1601 succs = tuple(parsenodeid(succ) for succ in successors)
1601 1602 l = repo.lock()
1602 1603 try:
1603 1604 tr = repo.transaction('debugobsolete')
1604 1605 try:
1605 1606 date = opts.get('date')
1606 1607 if date:
1607 1608 date = dateutil.parsedate(date)
1608 1609 else:
1609 1610 date = None
1610 1611 prec = parsenodeid(precursor)
1611 1612 parents = None
1612 1613 if opts['record_parents']:
1613 1614 if prec not in repo.unfiltered():
1614 1615 raise error.Abort('cannot used --record-parents on '
1615 1616 'unknown changesets')
1616 1617 parents = repo.unfiltered()[prec].parents()
1617 1618 parents = tuple(p.node() for p in parents)
1618 1619 repo.obsstore.create(tr, prec, succs, opts['flags'],
1619 1620 parents=parents, date=date,
1620 1621 metadata=metadata, ui=ui)
1621 1622 tr.close()
1622 1623 except ValueError as exc:
1623 1624 raise error.Abort(_('bad obsmarker input: %s') %
1624 1625 pycompat.bytestr(exc))
1625 1626 finally:
1626 1627 tr.release()
1627 1628 finally:
1628 1629 l.release()
1629 1630 else:
1630 1631 if opts['rev']:
1631 1632 revs = scmutil.revrange(repo, opts['rev'])
1632 1633 nodes = [repo[r].node() for r in revs]
1633 1634 markers = list(obsutil.getmarkers(repo, nodes=nodes,
1634 1635 exclusive=opts['exclusive']))
1635 1636 markers.sort(key=lambda x: x._data)
1636 1637 else:
1637 1638 markers = obsutil.getmarkers(repo)
1638 1639
1639 1640 markerstoiter = markers
1640 1641 isrelevant = lambda m: True
1641 1642 if opts.get('rev') and opts.get('index'):
1642 1643 markerstoiter = obsutil.getmarkers(repo)
1643 1644 markerset = set(markers)
1644 1645 isrelevant = lambda m: m in markerset
1645 1646
1646 1647 fm = ui.formatter('debugobsolete', opts)
1647 1648 for i, m in enumerate(markerstoiter):
1648 1649 if not isrelevant(m):
1649 1650 # marker can be irrelevant when we're iterating over a set
1650 1651 # of markers (markerstoiter) which is bigger than the set
1651 1652 # of markers we want to display (markers)
1652 1653 # this can happen if both --index and --rev options are
1653 1654 # provided and thus we need to iterate over all of the markers
1654 1655 # to get the correct indices, but only display the ones that
1655 1656 # are relevant to --rev value
1656 1657 continue
1657 1658 fm.startitem()
1658 1659 ind = i if opts.get('index') else None
1659 1660 cmdutil.showmarker(fm, m, index=ind)
1660 1661 fm.end()
1661 1662
1662 1663 @command('debugpathcomplete',
1663 1664 [('f', 'full', None, _('complete an entire path')),
1664 1665 ('n', 'normal', None, _('show only normal files')),
1665 1666 ('a', 'added', None, _('show only added files')),
1666 1667 ('r', 'removed', None, _('show only removed files'))],
1667 1668 _('FILESPEC...'))
1668 1669 def debugpathcomplete(ui, repo, *specs, **opts):
1669 1670 '''complete part or all of a tracked path
1670 1671
1671 1672 This command supports shells that offer path name completion. It
1672 1673 currently completes only files already known to the dirstate.
1673 1674
1674 1675 Completion extends only to the next path segment unless
1675 1676 --full is specified, in which case entire paths are used.'''
1676 1677
1677 1678 def complete(path, acceptable):
1678 1679 dirstate = repo.dirstate
1679 1680 spec = os.path.normpath(os.path.join(pycompat.getcwd(), path))
1680 1681 rootdir = repo.root + pycompat.ossep
1681 1682 if spec != repo.root and not spec.startswith(rootdir):
1682 1683 return [], []
1683 1684 if os.path.isdir(spec):
1684 1685 spec += '/'
1685 1686 spec = spec[len(rootdir):]
1686 1687 fixpaths = pycompat.ossep != '/'
1687 1688 if fixpaths:
1688 1689 spec = spec.replace(pycompat.ossep, '/')
1689 1690 speclen = len(spec)
1690 1691 fullpaths = opts[r'full']
1691 1692 files, dirs = set(), set()
1692 1693 adddir, addfile = dirs.add, files.add
1693 1694 for f, st in dirstate.iteritems():
1694 1695 if f.startswith(spec) and st[0] in acceptable:
1695 1696 if fixpaths:
1696 1697 f = f.replace('/', pycompat.ossep)
1697 1698 if fullpaths:
1698 1699 addfile(f)
1699 1700 continue
1700 1701 s = f.find(pycompat.ossep, speclen)
1701 1702 if s >= 0:
1702 1703 adddir(f[:s])
1703 1704 else:
1704 1705 addfile(f)
1705 1706 return files, dirs
1706 1707
1707 1708 acceptable = ''
1708 1709 if opts[r'normal']:
1709 1710 acceptable += 'nm'
1710 1711 if opts[r'added']:
1711 1712 acceptable += 'a'
1712 1713 if opts[r'removed']:
1713 1714 acceptable += 'r'
1714 1715 cwd = repo.getcwd()
1715 1716 if not specs:
1716 1717 specs = ['.']
1717 1718
1718 1719 files, dirs = set(), set()
1719 1720 for spec in specs:
1720 1721 f, d = complete(spec, acceptable or 'nmar')
1721 1722 files.update(f)
1722 1723 dirs.update(d)
1723 1724 files.update(dirs)
1724 1725 ui.write('\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
1725 1726 ui.write('\n')
1726 1727
1727 1728 @command('debugpeer', [], _('PATH'), norepo=True)
1728 1729 def debugpeer(ui, path):
1729 1730 """establish a connection to a peer repository"""
1730 1731 # Always enable peer request logging. Requires --debug to display
1731 1732 # though.
1732 1733 overrides = {
1733 1734 ('devel', 'debug.peer-request'): True,
1734 1735 }
1735 1736
1736 1737 with ui.configoverride(overrides):
1737 1738 peer = hg.peer(ui, {}, path)
1738 1739
1739 1740 local = peer.local() is not None
1740 1741 canpush = peer.canpush()
1741 1742
1742 1743 ui.write(_('url: %s\n') % peer.url())
1743 1744 ui.write(_('local: %s\n') % (_('yes') if local else _('no')))
1744 1745 ui.write(_('pushable: %s\n') % (_('yes') if canpush else _('no')))
1745 1746
1746 1747 @command('debugpickmergetool',
1747 1748 [('r', 'rev', '', _('check for files in this revision'), _('REV')),
1748 1749 ('', 'changedelete', None, _('emulate merging change and delete')),
1749 1750 ] + cmdutil.walkopts + cmdutil.mergetoolopts,
1750 1751 _('[PATTERN]...'),
1751 1752 inferrepo=True)
1752 1753 def debugpickmergetool(ui, repo, *pats, **opts):
1753 1754 """examine which merge tool is chosen for specified file
1754 1755
1755 1756 As described in :hg:`help merge-tools`, Mercurial examines
1756 1757 configurations below in this order to decide which merge tool is
1757 1758 chosen for specified file.
1758 1759
1759 1760 1. ``--tool`` option
1760 1761 2. ``HGMERGE`` environment variable
1761 1762 3. configurations in ``merge-patterns`` section
1762 1763 4. configuration of ``ui.merge``
1763 1764 5. configurations in ``merge-tools`` section
1764 1765 6. ``hgmerge`` tool (for historical reason only)
1765 1766 7. default tool for fallback (``:merge`` or ``:prompt``)
1766 1767
1767 1768 This command writes out examination result in the style below::
1768 1769
1769 1770 FILE = MERGETOOL
1770 1771
1771 1772 By default, all files known in the first parent context of the
1772 1773 working directory are examined. Use file patterns and/or -I/-X
1773 1774 options to limit target files. -r/--rev is also useful to examine
1774 1775 files in another context without actual updating to it.
1775 1776
1776 1777 With --debug, this command shows warning messages while matching
1777 1778 against ``merge-patterns`` and so on, too. It is recommended to
1778 1779 use this option with explicit file patterns and/or -I/-X options,
1779 1780 because this option increases amount of output per file according
1780 1781 to configurations in hgrc.
1781 1782
1782 1783 With -v/--verbose, this command shows configurations below at
1783 1784 first (only if specified).
1784 1785
1785 1786 - ``--tool`` option
1786 1787 - ``HGMERGE`` environment variable
1787 1788 - configuration of ``ui.merge``
1788 1789
1789 1790 If merge tool is chosen before matching against
1790 1791 ``merge-patterns``, this command can't show any helpful
1791 1792 information, even with --debug. In such case, information above is
1792 1793 useful to know why a merge tool is chosen.
1793 1794 """
1794 1795 opts = pycompat.byteskwargs(opts)
1795 1796 overrides = {}
1796 1797 if opts['tool']:
1797 1798 overrides[('ui', 'forcemerge')] = opts['tool']
1798 1799 ui.note(('with --tool %r\n') % (pycompat.bytestr(opts['tool'])))
1799 1800
1800 1801 with ui.configoverride(overrides, 'debugmergepatterns'):
1801 1802 hgmerge = encoding.environ.get("HGMERGE")
1802 1803 if hgmerge is not None:
1803 1804 ui.note(('with HGMERGE=%r\n') % (pycompat.bytestr(hgmerge)))
1804 1805 uimerge = ui.config("ui", "merge")
1805 1806 if uimerge:
1806 1807 ui.note(('with ui.merge=%r\n') % (pycompat.bytestr(uimerge)))
1807 1808
1808 1809 ctx = scmutil.revsingle(repo, opts.get('rev'))
1809 1810 m = scmutil.match(ctx, pats, opts)
1810 1811 changedelete = opts['changedelete']
1811 1812 for path in ctx.walk(m):
1812 1813 fctx = ctx[path]
1813 1814 try:
1814 1815 if not ui.debugflag:
1815 1816 ui.pushbuffer(error=True)
1816 1817 tool, toolpath = filemerge._picktool(repo, ui, path,
1817 1818 fctx.isbinary(),
1818 1819 'l' in fctx.flags(),
1819 1820 changedelete)
1820 1821 finally:
1821 1822 if not ui.debugflag:
1822 1823 ui.popbuffer()
1823 1824 ui.write(('%s = %s\n') % (path, tool))
1824 1825
1825 1826 @command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]'), norepo=True)
1826 1827 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
1827 1828 '''access the pushkey key/value protocol
1828 1829
1829 1830 With two args, list the keys in the given namespace.
1830 1831
1831 1832 With five args, set a key to new if it currently is set to old.
1832 1833 Reports success or failure.
1833 1834 '''
1834 1835
1835 1836 target = hg.peer(ui, {}, repopath)
1836 1837 if keyinfo:
1837 1838 key, old, new = keyinfo
1838 1839 with target.commandexecutor() as e:
1839 1840 r = e.callcommand('pushkey', {
1840 1841 'namespace': namespace,
1841 1842 'key': key,
1842 1843 'old': old,
1843 1844 'new': new,
1844 1845 }).result()
1845 1846
1846 1847 ui.status(pycompat.bytestr(r) + '\n')
1847 1848 return not r
1848 1849 else:
1849 1850 for k, v in sorted(target.listkeys(namespace).iteritems()):
1850 1851 ui.write("%s\t%s\n" % (stringutil.escapestr(k),
1851 1852 stringutil.escapestr(v)))
1852 1853
1853 1854 @command('debugpvec', [], _('A B'))
1854 1855 def debugpvec(ui, repo, a, b=None):
1855 1856 ca = scmutil.revsingle(repo, a)
1856 1857 cb = scmutil.revsingle(repo, b)
1857 1858 pa = pvec.ctxpvec(ca)
1858 1859 pb = pvec.ctxpvec(cb)
1859 1860 if pa == pb:
1860 1861 rel = "="
1861 1862 elif pa > pb:
1862 1863 rel = ">"
1863 1864 elif pa < pb:
1864 1865 rel = "<"
1865 1866 elif pa | pb:
1866 1867 rel = "|"
1867 1868 ui.write(_("a: %s\n") % pa)
1868 1869 ui.write(_("b: %s\n") % pb)
1869 1870 ui.write(_("depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth))
1870 1871 ui.write(_("delta: %d hdist: %d distance: %d relation: %s\n") %
1871 1872 (abs(pa._depth - pb._depth), pvec._hamming(pa._vec, pb._vec),
1872 1873 pa.distance(pb), rel))
1873 1874
1874 1875 @command('debugrebuilddirstate|debugrebuildstate',
1875 1876 [('r', 'rev', '', _('revision to rebuild to'), _('REV')),
1876 1877 ('', 'minimal', None, _('only rebuild files that are inconsistent with '
1877 1878 'the working copy parent')),
1878 1879 ],
1879 1880 _('[-r REV]'))
1880 1881 def debugrebuilddirstate(ui, repo, rev, **opts):
1881 1882 """rebuild the dirstate as it would look like for the given revision
1882 1883
1883 1884 If no revision is specified the first current parent will be used.
1884 1885
1885 1886 The dirstate will be set to the files of the given revision.
1886 1887 The actual working directory content or existing dirstate
1887 1888 information such as adds or removes is not considered.
1888 1889
1889 1890 ``minimal`` will only rebuild the dirstate status for files that claim to be
1890 1891 tracked but are not in the parent manifest, or that exist in the parent
1891 1892 manifest but are not in the dirstate. It will not change adds, removes, or
1892 1893 modified files that are in the working copy parent.
1893 1894
1894 1895 One use of this command is to make the next :hg:`status` invocation
1895 1896 check the actual file content.
1896 1897 """
1897 1898 ctx = scmutil.revsingle(repo, rev)
1898 1899 with repo.wlock():
1899 1900 dirstate = repo.dirstate
1900 1901 changedfiles = None
1901 1902 # See command doc for what minimal does.
1902 1903 if opts.get(r'minimal'):
1903 1904 manifestfiles = set(ctx.manifest().keys())
1904 1905 dirstatefiles = set(dirstate)
1905 1906 manifestonly = manifestfiles - dirstatefiles
1906 1907 dsonly = dirstatefiles - manifestfiles
1907 1908 dsnotadded = set(f for f in dsonly if dirstate[f] != 'a')
1908 1909 changedfiles = manifestonly | dsnotadded
1909 1910
1910 1911 dirstate.rebuild(ctx.node(), ctx.manifest(), changedfiles)
1911 1912
1912 1913 @command('debugrebuildfncache', [], '')
1913 1914 def debugrebuildfncache(ui, repo):
1914 1915 """rebuild the fncache file"""
1915 1916 repair.rebuildfncache(ui, repo)
1916 1917
1917 1918 @command('debugrename',
1918 1919 [('r', 'rev', '', _('revision to debug'), _('REV'))],
1919 1920 _('[-r REV] FILE'))
1920 1921 def debugrename(ui, repo, file1, *pats, **opts):
1921 1922 """dump rename information"""
1922 1923
1923 1924 opts = pycompat.byteskwargs(opts)
1924 1925 ctx = scmutil.revsingle(repo, opts.get('rev'))
1925 1926 m = scmutil.match(ctx, (file1,) + pats, opts)
1926 1927 for abs in ctx.walk(m):
1927 1928 fctx = ctx[abs]
1928 1929 o = fctx.filelog().renamed(fctx.filenode())
1929 1930 rel = m.rel(abs)
1930 1931 if o:
1931 1932 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
1932 1933 else:
1933 1934 ui.write(_("%s not renamed\n") % rel)
1934 1935
1935 1936 @command('debugrevlog', cmdutil.debugrevlogopts +
1936 1937 [('d', 'dump', False, _('dump index data'))],
1937 1938 _('-c|-m|FILE'),
1938 1939 optionalrepo=True)
1939 1940 def debugrevlog(ui, repo, file_=None, **opts):
1940 1941 """show data and statistics about a revlog"""
1941 1942 opts = pycompat.byteskwargs(opts)
1942 1943 r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
1943 1944
1944 1945 if opts.get("dump"):
1945 1946 numrevs = len(r)
1946 1947 ui.write(("# rev p1rev p2rev start end deltastart base p1 p2"
1947 1948 " rawsize totalsize compression heads chainlen\n"))
1948 1949 ts = 0
1949 1950 heads = set()
1950 1951
1951 1952 for rev in xrange(numrevs):
1952 1953 dbase = r.deltaparent(rev)
1953 1954 if dbase == -1:
1954 1955 dbase = rev
1955 1956 cbase = r.chainbase(rev)
1956 1957 clen = r.chainlen(rev)
1957 1958 p1, p2 = r.parentrevs(rev)
1958 1959 rs = r.rawsize(rev)
1959 1960 ts = ts + rs
1960 1961 heads -= set(r.parentrevs(rev))
1961 1962 heads.add(rev)
1962 1963 try:
1963 1964 compression = ts / r.end(rev)
1964 1965 except ZeroDivisionError:
1965 1966 compression = 0
1966 1967 ui.write("%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
1967 1968 "%11d %5d %8d\n" %
1968 1969 (rev, p1, p2, r.start(rev), r.end(rev),
1969 1970 r.start(dbase), r.start(cbase),
1970 1971 r.start(p1), r.start(p2),
1971 1972 rs, ts, compression, len(heads), clen))
1972 1973 return 0
1973 1974
1974 1975 v = r.version
1975 1976 format = v & 0xFFFF
1976 1977 flags = []
1977 1978 gdelta = False
1978 1979 if v & revlog.FLAG_INLINE_DATA:
1979 1980 flags.append('inline')
1980 1981 if v & revlog.FLAG_GENERALDELTA:
1981 1982 gdelta = True
1982 1983 flags.append('generaldelta')
1983 1984 if not flags:
1984 1985 flags = ['(none)']
1985 1986
1986 1987 nummerges = 0
1987 1988 numfull = 0
1988 1989 numprev = 0
1989 1990 nump1 = 0
1990 1991 nump2 = 0
1991 1992 numother = 0
1992 1993 nump1prev = 0
1993 1994 nump2prev = 0
1994 1995 chainlengths = []
1995 1996 chainbases = []
1996 1997 chainspans = []
1997 1998
1998 1999 datasize = [None, 0, 0]
1999 2000 fullsize = [None, 0, 0]
2000 2001 deltasize = [None, 0, 0]
2001 2002 chunktypecounts = {}
2002 2003 chunktypesizes = {}
2003 2004
2004 2005 def addsize(size, l):
2005 2006 if l[0] is None or size < l[0]:
2006 2007 l[0] = size
2007 2008 if size > l[1]:
2008 2009 l[1] = size
2009 2010 l[2] += size
2010 2011
2011 2012 numrevs = len(r)
2012 2013 for rev in xrange(numrevs):
2013 2014 p1, p2 = r.parentrevs(rev)
2014 2015 delta = r.deltaparent(rev)
2015 2016 if format > 0:
2016 2017 addsize(r.rawsize(rev), datasize)
2017 2018 if p2 != nullrev:
2018 2019 nummerges += 1
2019 2020 size = r.length(rev)
2020 2021 if delta == nullrev:
2021 2022 chainlengths.append(0)
2022 2023 chainbases.append(r.start(rev))
2023 2024 chainspans.append(size)
2024 2025 numfull += 1
2025 2026 addsize(size, fullsize)
2026 2027 else:
2027 2028 chainlengths.append(chainlengths[delta] + 1)
2028 2029 baseaddr = chainbases[delta]
2029 2030 revaddr = r.start(rev)
2030 2031 chainbases.append(baseaddr)
2031 2032 chainspans.append((revaddr - baseaddr) + size)
2032 2033 addsize(size, deltasize)
2033 2034 if delta == rev - 1:
2034 2035 numprev += 1
2035 2036 if delta == p1:
2036 2037 nump1prev += 1
2037 2038 elif delta == p2:
2038 2039 nump2prev += 1
2039 2040 elif delta == p1:
2040 2041 nump1 += 1
2041 2042 elif delta == p2:
2042 2043 nump2 += 1
2043 2044 elif delta != nullrev:
2044 2045 numother += 1
2045 2046
2046 2047 # Obtain data on the raw chunks in the revlog.
2047 2048 segment = r._getsegmentforrevs(rev, rev)[1]
2048 2049 if segment:
2049 2050 chunktype = bytes(segment[0:1])
2050 2051 else:
2051 2052 chunktype = 'empty'
2052 2053
2053 2054 if chunktype not in chunktypecounts:
2054 2055 chunktypecounts[chunktype] = 0
2055 2056 chunktypesizes[chunktype] = 0
2056 2057
2057 2058 chunktypecounts[chunktype] += 1
2058 2059 chunktypesizes[chunktype] += size
2059 2060
2060 2061 # Adjust size min value for empty cases
2061 2062 for size in (datasize, fullsize, deltasize):
2062 2063 if size[0] is None:
2063 2064 size[0] = 0
2064 2065
2065 2066 numdeltas = numrevs - numfull
2066 2067 numoprev = numprev - nump1prev - nump2prev
2067 2068 totalrawsize = datasize[2]
2068 2069 datasize[2] /= numrevs
2069 2070 fulltotal = fullsize[2]
2070 2071 fullsize[2] /= numfull
2071 2072 deltatotal = deltasize[2]
2072 2073 if numrevs - numfull > 0:
2073 2074 deltasize[2] /= numrevs - numfull
2074 2075 totalsize = fulltotal + deltatotal
2075 2076 avgchainlen = sum(chainlengths) / numrevs
2076 2077 maxchainlen = max(chainlengths)
2077 2078 maxchainspan = max(chainspans)
2078 2079 compratio = 1
2079 2080 if totalsize:
2080 2081 compratio = totalrawsize / totalsize
2081 2082
2082 2083 basedfmtstr = '%%%dd\n'
2083 2084 basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
2084 2085
2085 2086 def dfmtstr(max):
2086 2087 return basedfmtstr % len(str(max))
2087 2088 def pcfmtstr(max, padding=0):
2088 2089 return basepcfmtstr % (len(str(max)), ' ' * padding)
2089 2090
2090 2091 def pcfmt(value, total):
2091 2092 if total:
2092 2093 return (value, 100 * float(value) / total)
2093 2094 else:
2094 2095 return value, 100.0
2095 2096
2096 2097 ui.write(('format : %d\n') % format)
2097 2098 ui.write(('flags : %s\n') % ', '.join(flags))
2098 2099
2099 2100 ui.write('\n')
2100 2101 fmt = pcfmtstr(totalsize)
2101 2102 fmt2 = dfmtstr(totalsize)
2102 2103 ui.write(('revisions : ') + fmt2 % numrevs)
2103 2104 ui.write((' merges : ') + fmt % pcfmt(nummerges, numrevs))
2104 2105 ui.write((' normal : ') + fmt % pcfmt(numrevs - nummerges, numrevs))
2105 2106 ui.write(('revisions : ') + fmt2 % numrevs)
2106 2107 ui.write((' full : ') + fmt % pcfmt(numfull, numrevs))
2107 2108 ui.write((' deltas : ') + fmt % pcfmt(numdeltas, numrevs))
2108 2109 ui.write(('revision size : ') + fmt2 % totalsize)
2109 2110 ui.write((' full : ') + fmt % pcfmt(fulltotal, totalsize))
2110 2111 ui.write((' deltas : ') + fmt % pcfmt(deltatotal, totalsize))
2111 2112
2112 2113 def fmtchunktype(chunktype):
2113 2114 if chunktype == 'empty':
2114 2115 return ' %s : ' % chunktype
2115 2116 elif chunktype in pycompat.bytestr(string.ascii_letters):
2116 2117 return ' 0x%s (%s) : ' % (hex(chunktype), chunktype)
2117 2118 else:
2118 2119 return ' 0x%s : ' % hex(chunktype)
2119 2120
2120 2121 ui.write('\n')
2121 2122 ui.write(('chunks : ') + fmt2 % numrevs)
2122 2123 for chunktype in sorted(chunktypecounts):
2123 2124 ui.write(fmtchunktype(chunktype))
2124 2125 ui.write(fmt % pcfmt(chunktypecounts[chunktype], numrevs))
2125 2126 ui.write(('chunks size : ') + fmt2 % totalsize)
2126 2127 for chunktype in sorted(chunktypecounts):
2127 2128 ui.write(fmtchunktype(chunktype))
2128 2129 ui.write(fmt % pcfmt(chunktypesizes[chunktype], totalsize))
2129 2130
2130 2131 ui.write('\n')
2131 2132 fmt = dfmtstr(max(avgchainlen, maxchainlen, maxchainspan, compratio))
2132 2133 ui.write(('avg chain length : ') + fmt % avgchainlen)
2133 2134 ui.write(('max chain length : ') + fmt % maxchainlen)
2134 2135 ui.write(('max chain reach : ') + fmt % maxchainspan)
2135 2136 ui.write(('compression ratio : ') + fmt % compratio)
2136 2137
2137 2138 if format > 0:
2138 2139 ui.write('\n')
2139 2140 ui.write(('uncompressed data size (min/max/avg) : %d / %d / %d\n')
2140 2141 % tuple(datasize))
2141 2142 ui.write(('full revision size (min/max/avg) : %d / %d / %d\n')
2142 2143 % tuple(fullsize))
2143 2144 ui.write(('delta size (min/max/avg) : %d / %d / %d\n')
2144 2145 % tuple(deltasize))
2145 2146
2146 2147 if numdeltas > 0:
2147 2148 ui.write('\n')
2148 2149 fmt = pcfmtstr(numdeltas)
2149 2150 fmt2 = pcfmtstr(numdeltas, 4)
2150 2151 ui.write(('deltas against prev : ') + fmt % pcfmt(numprev, numdeltas))
2151 2152 if numprev > 0:
2152 2153 ui.write((' where prev = p1 : ') + fmt2 % pcfmt(nump1prev,
2153 2154 numprev))
2154 2155 ui.write((' where prev = p2 : ') + fmt2 % pcfmt(nump2prev,
2155 2156 numprev))
2156 2157 ui.write((' other : ') + fmt2 % pcfmt(numoprev,
2157 2158 numprev))
2158 2159 if gdelta:
2159 2160 ui.write(('deltas against p1 : ')
2160 2161 + fmt % pcfmt(nump1, numdeltas))
2161 2162 ui.write(('deltas against p2 : ')
2162 2163 + fmt % pcfmt(nump2, numdeltas))
2163 2164 ui.write(('deltas against other : ') + fmt % pcfmt(numother,
2164 2165 numdeltas))
2165 2166
2166 2167 @command('debugrevspec',
2167 2168 [('', 'optimize', None,
2168 2169 _('print parsed tree after optimizing (DEPRECATED)')),
2169 2170 ('', 'show-revs', True, _('print list of result revisions (default)')),
2170 2171 ('s', 'show-set', None, _('print internal representation of result set')),
2171 2172 ('p', 'show-stage', [],
2172 2173 _('print parsed tree at the given stage'), _('NAME')),
2173 2174 ('', 'no-optimized', False, _('evaluate tree without optimization')),
2174 2175 ('', 'verify-optimized', False, _('verify optimized result')),
2175 2176 ],
2176 2177 ('REVSPEC'))
2177 2178 def debugrevspec(ui, repo, expr, **opts):
2178 2179 """parse and apply a revision specification
2179 2180
2180 2181 Use -p/--show-stage option to print the parsed tree at the given stages.
2181 2182 Use -p all to print tree at every stage.
2182 2183
2183 2184 Use --no-show-revs option with -s or -p to print only the set
2184 2185 representation or the parsed tree respectively.
2185 2186
2186 2187 Use --verify-optimized to compare the optimized result with the unoptimized
2187 2188 one. Returns 1 if the optimized result differs.
2188 2189 """
2189 2190 opts = pycompat.byteskwargs(opts)
2190 2191 aliases = ui.configitems('revsetalias')
2191 2192 stages = [
2192 2193 ('parsed', lambda tree: tree),
2193 2194 ('expanded', lambda tree: revsetlang.expandaliases(tree, aliases,
2194 2195 ui.warn)),
2195 2196 ('concatenated', revsetlang.foldconcat),
2196 2197 ('analyzed', revsetlang.analyze),
2197 2198 ('optimized', revsetlang.optimize),
2198 2199 ]
2199 2200 if opts['no_optimized']:
2200 2201 stages = stages[:-1]
2201 2202 if opts['verify_optimized'] and opts['no_optimized']:
2202 2203 raise error.Abort(_('cannot use --verify-optimized with '
2203 2204 '--no-optimized'))
2204 2205 stagenames = set(n for n, f in stages)
2205 2206
2206 2207 showalways = set()
2207 2208 showchanged = set()
2208 2209 if ui.verbose and not opts['show_stage']:
2209 2210 # show parsed tree by --verbose (deprecated)
2210 2211 showalways.add('parsed')
2211 2212 showchanged.update(['expanded', 'concatenated'])
2212 2213 if opts['optimize']:
2213 2214 showalways.add('optimized')
2214 2215 if opts['show_stage'] and opts['optimize']:
2215 2216 raise error.Abort(_('cannot use --optimize with --show-stage'))
2216 2217 if opts['show_stage'] == ['all']:
2217 2218 showalways.update(stagenames)
2218 2219 else:
2219 2220 for n in opts['show_stage']:
2220 2221 if n not in stagenames:
2221 2222 raise error.Abort(_('invalid stage name: %s') % n)
2222 2223 showalways.update(opts['show_stage'])
2223 2224
2224 2225 treebystage = {}
2225 2226 printedtree = None
2226 2227 tree = revsetlang.parse(expr, lookup=revset.lookupfn(repo))
2227 2228 for n, f in stages:
2228 2229 treebystage[n] = tree = f(tree)
2229 2230 if n in showalways or (n in showchanged and tree != printedtree):
2230 2231 if opts['show_stage'] or n != 'parsed':
2231 2232 ui.write(("* %s:\n") % n)
2232 2233 ui.write(revsetlang.prettyformat(tree), "\n")
2233 2234 printedtree = tree
2234 2235
2235 2236 if opts['verify_optimized']:
2236 2237 arevs = revset.makematcher(treebystage['analyzed'])(repo)
2237 2238 brevs = revset.makematcher(treebystage['optimized'])(repo)
2238 2239 if opts['show_set'] or (opts['show_set'] is None and ui.verbose):
2239 2240 ui.write(("* analyzed set:\n"), smartset.prettyformat(arevs), "\n")
2240 2241 ui.write(("* optimized set:\n"), smartset.prettyformat(brevs), "\n")
2241 2242 arevs = list(arevs)
2242 2243 brevs = list(brevs)
2243 2244 if arevs == brevs:
2244 2245 return 0
2245 2246 ui.write(('--- analyzed\n'), label='diff.file_a')
2246 2247 ui.write(('+++ optimized\n'), label='diff.file_b')
2247 2248 sm = difflib.SequenceMatcher(None, arevs, brevs)
2248 2249 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
2249 2250 if tag in ('delete', 'replace'):
2250 2251 for c in arevs[alo:ahi]:
2251 2252 ui.write('-%s\n' % c, label='diff.deleted')
2252 2253 if tag in ('insert', 'replace'):
2253 2254 for c in brevs[blo:bhi]:
2254 2255 ui.write('+%s\n' % c, label='diff.inserted')
2255 2256 if tag == 'equal':
2256 2257 for c in arevs[alo:ahi]:
2257 2258 ui.write(' %s\n' % c)
2258 2259 return 1
2259 2260
2260 2261 func = revset.makematcher(tree)
2261 2262 revs = func(repo)
2262 2263 if opts['show_set'] or (opts['show_set'] is None and ui.verbose):
2263 2264 ui.write(("* set:\n"), smartset.prettyformat(revs), "\n")
2264 2265 if not opts['show_revs']:
2265 2266 return
2266 2267 for c in revs:
2267 2268 ui.write("%d\n" % c)
2268 2269
2269 2270 @command('debugserve', [
2270 2271 ('', 'sshstdio', False, _('run an SSH server bound to process handles')),
2271 2272 ('', 'logiofd', '', _('file descriptor to log server I/O to')),
2272 2273 ('', 'logiofile', '', _('file to log server I/O to')),
2273 2274 ], '')
2274 2275 def debugserve(ui, repo, **opts):
2275 2276 """run a server with advanced settings
2276 2277
2277 2278 This command is similar to :hg:`serve`. It exists partially as a
2278 2279 workaround to the fact that ``hg serve --stdio`` must have specific
2279 2280 arguments for security reasons.
2280 2281 """
2281 2282 opts = pycompat.byteskwargs(opts)
2282 2283
2283 2284 if not opts['sshstdio']:
2284 2285 raise error.Abort(_('only --sshstdio is currently supported'))
2285 2286
2286 2287 logfh = None
2287 2288
2288 2289 if opts['logiofd'] and opts['logiofile']:
2289 2290 raise error.Abort(_('cannot use both --logiofd and --logiofile'))
2290 2291
2291 2292 if opts['logiofd']:
2292 2293 # Line buffered because output is line based.
2293 2294 logfh = os.fdopen(int(opts['logiofd']), r'ab', 1)
2294 2295 elif opts['logiofile']:
2295 2296 logfh = open(opts['logiofile'], 'ab', 1)
2296 2297
2297 2298 s = wireprotoserver.sshserver(ui, repo, logfh=logfh)
2298 2299 s.serve_forever()
2299 2300
2300 2301 @command('debugsetparents', [], _('REV1 [REV2]'))
2301 2302 def debugsetparents(ui, repo, rev1, rev2=None):
2302 2303 """manually set the parents of the current working directory
2303 2304
2304 2305 This is useful for writing repository conversion tools, but should
2305 2306 be used with care. For example, neither the working directory nor the
2306 2307 dirstate is updated, so file status may be incorrect after running this
2307 2308 command.
2308 2309
2309 2310 Returns 0 on success.
2310 2311 """
2311 2312
2312 2313 node1 = scmutil.revsingle(repo, rev1).node()
2313 2314 node2 = scmutil.revsingle(repo, rev2, 'null').node()
2314 2315
2315 2316 with repo.wlock():
2316 2317 repo.setparents(node1, node2)
2317 2318
2318 2319 @command('debugssl', [], '[SOURCE]', optionalrepo=True)
2319 2320 def debugssl(ui, repo, source=None, **opts):
2320 2321 '''test a secure connection to a server
2321 2322
2322 2323 This builds the certificate chain for the server on Windows, installing the
2323 2324 missing intermediates and trusted root via Windows Update if necessary. It
2324 2325 does nothing on other platforms.
2325 2326
2326 2327 If SOURCE is omitted, the 'default' path will be used. If a URL is given,
2327 2328 that server is used. See :hg:`help urls` for more information.
2328 2329
2329 2330 If the update succeeds, retry the original operation. Otherwise, the cause
2330 2331 of the SSL error is likely another issue.
2331 2332 '''
2332 2333 if not pycompat.iswindows:
2333 2334 raise error.Abort(_('certificate chain building is only possible on '
2334 2335 'Windows'))
2335 2336
2336 2337 if not source:
2337 2338 if not repo:
2338 2339 raise error.Abort(_("there is no Mercurial repository here, and no "
2339 2340 "server specified"))
2340 2341 source = "default"
2341 2342
2342 2343 source, branches = hg.parseurl(ui.expandpath(source))
2343 2344 url = util.url(source)
2344 2345 addr = None
2345 2346
2346 2347 defaultport = {'https': 443, 'ssh': 22}
2347 2348 if url.scheme in defaultport:
2348 2349 try:
2349 2350 addr = (url.host, int(url.port or defaultport[url.scheme]))
2350 2351 except ValueError:
2351 2352 raise error.Abort(_("malformed port number in URL"))
2352 2353 else:
2353 2354 raise error.Abort(_("only https and ssh connections are supported"))
2354 2355
2355 2356 from . import win32
2356 2357
2357 2358 s = ssl.wrap_socket(socket.socket(), ssl_version=ssl.PROTOCOL_TLS,
2358 2359 cert_reqs=ssl.CERT_NONE, ca_certs=None)
2359 2360
2360 2361 try:
2361 2362 s.connect(addr)
2362 2363 cert = s.getpeercert(True)
2363 2364
2364 2365 ui.status(_('checking the certificate chain for %s\n') % url.host)
2365 2366
2366 2367 complete = win32.checkcertificatechain(cert, build=False)
2367 2368
2368 2369 if not complete:
2369 2370 ui.status(_('certificate chain is incomplete, updating... '))
2370 2371
2371 2372 if not win32.checkcertificatechain(cert):
2372 2373 ui.status(_('failed.\n'))
2373 2374 else:
2374 2375 ui.status(_('done.\n'))
2375 2376 else:
2376 2377 ui.status(_('full certificate chain is available\n'))
2377 2378 finally:
2378 2379 s.close()
2379 2380
2380 2381 @command('debugsub',
2381 2382 [('r', 'rev', '',
2382 2383 _('revision to check'), _('REV'))],
2383 2384 _('[-r REV] [REV]'))
2384 2385 def debugsub(ui, repo, rev=None):
2385 2386 ctx = scmutil.revsingle(repo, rev, None)
2386 2387 for k, v in sorted(ctx.substate.items()):
2387 2388 ui.write(('path %s\n') % k)
2388 2389 ui.write((' source %s\n') % v[0])
2389 2390 ui.write((' revision %s\n') % v[1])
2390 2391
2391 2392 @command('debugsuccessorssets',
2392 2393 [('', 'closest', False, _('return closest successors sets only'))],
2393 2394 _('[REV]'))
2394 2395 def debugsuccessorssets(ui, repo, *revs, **opts):
2395 2396 """show set of successors for revision
2396 2397
2397 2398 A successors set of changeset A is a consistent group of revisions that
2398 2399 succeed A. It contains non-obsolete changesets only unless closests
2399 2400 successors set is set.
2400 2401
2401 2402 In most cases a changeset A has a single successors set containing a single
2402 2403 successor (changeset A replaced by A').
2403 2404
2404 2405 A changeset that is made obsolete with no successors are called "pruned".
2405 2406 Such changesets have no successors sets at all.
2406 2407
2407 2408 A changeset that has been "split" will have a successors set containing
2408 2409 more than one successor.
2409 2410
2410 2411 A changeset that has been rewritten in multiple different ways is called
2411 2412 "divergent". Such changesets have multiple successor sets (each of which
2412 2413 may also be split, i.e. have multiple successors).
2413 2414
2414 2415 Results are displayed as follows::
2415 2416
2416 2417 <rev1>
2417 2418 <successors-1A>
2418 2419 <rev2>
2419 2420 <successors-2A>
2420 2421 <successors-2B1> <successors-2B2> <successors-2B3>
2421 2422
2422 2423 Here rev2 has two possible (i.e. divergent) successors sets. The first
2423 2424 holds one element, whereas the second holds three (i.e. the changeset has
2424 2425 been split).
2425 2426 """
2426 2427 # passed to successorssets caching computation from one call to another
2427 2428 cache = {}
2428 2429 ctx2str = bytes
2429 2430 node2str = short
2430 2431 for rev in scmutil.revrange(repo, revs):
2431 2432 ctx = repo[rev]
2432 2433 ui.write('%s\n'% ctx2str(ctx))
2433 2434 for succsset in obsutil.successorssets(repo, ctx.node(),
2434 2435 closest=opts[r'closest'],
2435 2436 cache=cache):
2436 2437 if succsset:
2437 2438 ui.write(' ')
2438 2439 ui.write(node2str(succsset[0]))
2439 2440 for node in succsset[1:]:
2440 2441 ui.write(' ')
2441 2442 ui.write(node2str(node))
2442 2443 ui.write('\n')
2443 2444
2444 2445 @command('debugtemplate',
2445 2446 [('r', 'rev', [], _('apply template on changesets'), _('REV')),
2446 2447 ('D', 'define', [], _('define template keyword'), _('KEY=VALUE'))],
2447 2448 _('[-r REV]... [-D KEY=VALUE]... TEMPLATE'),
2448 2449 optionalrepo=True)
2449 2450 def debugtemplate(ui, repo, tmpl, **opts):
2450 2451 """parse and apply a template
2451 2452
2452 2453 If -r/--rev is given, the template is processed as a log template and
2453 2454 applied to the given changesets. Otherwise, it is processed as a generic
2454 2455 template.
2455 2456
2456 2457 Use --verbose to print the parsed tree.
2457 2458 """
2458 2459 revs = None
2459 2460 if opts[r'rev']:
2460 2461 if repo is None:
2461 2462 raise error.RepoError(_('there is no Mercurial repository here '
2462 2463 '(.hg not found)'))
2463 2464 revs = scmutil.revrange(repo, opts[r'rev'])
2464 2465
2465 2466 props = {}
2466 2467 for d in opts[r'define']:
2467 2468 try:
2468 2469 k, v = (e.strip() for e in d.split('=', 1))
2469 2470 if not k or k == 'ui':
2470 2471 raise ValueError
2471 2472 props[k] = v
2472 2473 except ValueError:
2473 2474 raise error.Abort(_('malformed keyword definition: %s') % d)
2474 2475
2475 2476 if ui.verbose:
2476 2477 aliases = ui.configitems('templatealias')
2477 2478 tree = templater.parse(tmpl)
2478 2479 ui.note(templater.prettyformat(tree), '\n')
2479 2480 newtree = templater.expandaliases(tree, aliases)
2480 2481 if newtree != tree:
2481 2482 ui.note(("* expanded:\n"), templater.prettyformat(newtree), '\n')
2482 2483
2483 2484 if revs is None:
2484 2485 tres = formatter.templateresources(ui, repo)
2485 2486 t = formatter.maketemplater(ui, tmpl, resources=tres)
2486 2487 ui.write(t.renderdefault(props))
2487 2488 else:
2488 2489 displayer = logcmdutil.maketemplater(ui, repo, tmpl)
2489 2490 for r in revs:
2490 2491 displayer.show(repo[r], **pycompat.strkwargs(props))
2491 2492 displayer.close()
2492 2493
2493 2494 @command('debuguigetpass', [
2494 2495 ('p', 'prompt', '', _('prompt text'), _('TEXT')),
2495 2496 ], _('[-p TEXT]'), norepo=True)
2496 2497 def debuguigetpass(ui, prompt=''):
2497 2498 """show prompt to type password"""
2498 2499 r = ui.getpass(prompt)
2499 2500 ui.write(('respose: %s\n') % r)
2500 2501
2501 2502 @command('debuguiprompt', [
2502 2503 ('p', 'prompt', '', _('prompt text'), _('TEXT')),
2503 2504 ], _('[-p TEXT]'), norepo=True)
2504 2505 def debuguiprompt(ui, prompt=''):
2505 2506 """show plain prompt"""
2506 2507 r = ui.prompt(prompt)
2507 2508 ui.write(('response: %s\n') % r)
2508 2509
2509 2510 @command('debugupdatecaches', [])
2510 2511 def debugupdatecaches(ui, repo, *pats, **opts):
2511 2512 """warm all known caches in the repository"""
2512 2513 with repo.wlock(), repo.lock():
2513 2514 repo.updatecaches(full=True)
2514 2515
2515 2516 @command('debugupgraderepo', [
2516 2517 ('o', 'optimize', [], _('extra optimization to perform'), _('NAME')),
2517 2518 ('', 'run', False, _('performs an upgrade')),
2518 2519 ])
2519 2520 def debugupgraderepo(ui, repo, run=False, optimize=None):
2520 2521 """upgrade a repository to use different features
2521 2522
2522 2523 If no arguments are specified, the repository is evaluated for upgrade
2523 2524 and a list of problems and potential optimizations is printed.
2524 2525
2525 2526 With ``--run``, a repository upgrade is performed. Behavior of the upgrade
2526 2527 can be influenced via additional arguments. More details will be provided
2527 2528 by the command output when run without ``--run``.
2528 2529
2529 2530 During the upgrade, the repository will be locked and no writes will be
2530 2531 allowed.
2531 2532
2532 2533 At the end of the upgrade, the repository may not be readable while new
2533 2534 repository data is swapped in. This window will be as long as it takes to
2534 2535 rename some directories inside the ``.hg`` directory. On most machines, this
2535 2536 should complete almost instantaneously and the chances of a consumer being
2536 2537 unable to access the repository should be low.
2537 2538 """
2538 2539 return upgrade.upgraderepo(ui, repo, run=run, optimize=optimize)
2539 2540
2540 2541 @command('debugwalk', cmdutil.walkopts, _('[OPTION]... [FILE]...'),
2541 2542 inferrepo=True)
2542 2543 def debugwalk(ui, repo, *pats, **opts):
2543 2544 """show how files match on given patterns"""
2544 2545 opts = pycompat.byteskwargs(opts)
2545 2546 m = scmutil.match(repo[None], pats, opts)
2546 2547 ui.write(('matcher: %r\n' % m))
2547 2548 items = list(repo[None].walk(m))
2548 2549 if not items:
2549 2550 return
2550 2551 f = lambda fn: fn
2551 2552 if ui.configbool('ui', 'slash') and pycompat.ossep != '/':
2552 2553 f = lambda fn: util.normpath(fn)
2553 2554 fmt = 'f %%-%ds %%-%ds %%s' % (
2554 2555 max([len(abs) for abs in items]),
2555 2556 max([len(m.rel(abs)) for abs in items]))
2556 2557 for abs in items:
2557 2558 line = fmt % (abs, f(m.rel(abs)), m.exact(abs) and 'exact' or '')
2558 2559 ui.write("%s\n" % line.rstrip())
2559 2560
2560 2561 @command('debugwhyunstable', [], _('REV'))
2561 2562 def debugwhyunstable(ui, repo, rev):
2562 2563 """explain instabilities of a changeset"""
2563 2564 for entry in obsutil.whyunstable(repo, scmutil.revsingle(repo, rev)):
2564 2565 dnodes = ''
2565 2566 if entry.get('divergentnodes'):
2566 2567 dnodes = ' '.join('%s (%s)' % (ctx.hex(), ctx.phasestr())
2567 2568 for ctx in entry['divergentnodes']) + ' '
2568 2569 ui.write('%s: %s%s %s\n' % (entry['instability'], dnodes,
2569 2570 entry['reason'], entry['node']))
2570 2571
2571 2572 @command('debugwireargs',
2572 2573 [('', 'three', '', 'three'),
2573 2574 ('', 'four', '', 'four'),
2574 2575 ('', 'five', '', 'five'),
2575 2576 ] + cmdutil.remoteopts,
2576 2577 _('REPO [OPTIONS]... [ONE [TWO]]'),
2577 2578 norepo=True)
2578 2579 def debugwireargs(ui, repopath, *vals, **opts):
2579 2580 opts = pycompat.byteskwargs(opts)
2580 2581 repo = hg.peer(ui, opts, repopath)
2581 2582 for opt in cmdutil.remoteopts:
2582 2583 del opts[opt[1]]
2583 2584 args = {}
2584 2585 for k, v in opts.iteritems():
2585 2586 if v:
2586 2587 args[k] = v
2587 2588 args = pycompat.strkwargs(args)
2588 2589 # run twice to check that we don't mess up the stream for the next command
2589 2590 res1 = repo.debugwireargs(*vals, **args)
2590 2591 res2 = repo.debugwireargs(*vals, **args)
2591 2592 ui.write("%s\n" % res1)
2592 2593 if res1 != res2:
2593 2594 ui.warn("%s\n" % res2)
2594 2595
2595 2596 def _parsewirelangblocks(fh):
2596 2597 activeaction = None
2597 2598 blocklines = []
2598 2599
2599 2600 for line in fh:
2600 2601 line = line.rstrip()
2601 2602 if not line:
2602 2603 continue
2603 2604
2604 2605 if line.startswith(b'#'):
2605 2606 continue
2606 2607
2607 2608 if not line.startswith(' '):
2608 2609 # New block. Flush previous one.
2609 2610 if activeaction:
2610 2611 yield activeaction, blocklines
2611 2612
2612 2613 activeaction = line
2613 2614 blocklines = []
2614 2615 continue
2615 2616
2616 2617 # Else we start with an indent.
2617 2618
2618 2619 if not activeaction:
2619 2620 raise error.Abort(_('indented line outside of block'))
2620 2621
2621 2622 blocklines.append(line)
2622 2623
2623 2624 # Flush last block.
2624 2625 if activeaction:
2625 2626 yield activeaction, blocklines
2626 2627
2627 2628 @command('debugwireproto',
2628 2629 [
2629 2630 ('', 'localssh', False, _('start an SSH server for this repo')),
2630 2631 ('', 'peer', '', _('construct a specific version of the peer')),
2631 2632 ('', 'noreadstderr', False, _('do not read from stderr of the remote')),
2632 2633 ('', 'nologhandshake', False,
2633 2634 _('do not log I/O related to the peer handshake')),
2634 2635 ] + cmdutil.remoteopts,
2635 2636 _('[PATH]'),
2636 2637 optionalrepo=True)
2637 2638 def debugwireproto(ui, repo, path=None, **opts):
2638 2639 """send wire protocol commands to a server
2639 2640
2640 2641 This command can be used to issue wire protocol commands to remote
2641 2642 peers and to debug the raw data being exchanged.
2642 2643
2643 2644 ``--localssh`` will start an SSH server against the current repository
2644 2645 and connect to that. By default, the connection will perform a handshake
2645 2646 and establish an appropriate peer instance.
2646 2647
2647 2648 ``--peer`` can be used to bypass the handshake protocol and construct a
2648 2649 peer instance using the specified class type. Valid values are ``raw``,
2649 2650 ``http2``, ``ssh1``, and ``ssh2``. ``raw`` instances only allow sending
2650 2651 raw data payloads and don't support higher-level command actions.
2651 2652
2652 2653 ``--noreadstderr`` can be used to disable automatic reading from stderr
2653 2654 of the peer (for SSH connections only). Disabling automatic reading of
2654 2655 stderr is useful for making output more deterministic.
2655 2656
2656 2657 Commands are issued via a mini language which is specified via stdin.
2657 2658 The language consists of individual actions to perform. An action is
2658 2659 defined by a block. A block is defined as a line with no leading
2659 2660 space followed by 0 or more lines with leading space. Blocks are
2660 2661 effectively a high-level command with additional metadata.
2661 2662
2662 2663 Lines beginning with ``#`` are ignored.
2663 2664
2664 2665 The following sections denote available actions.
2665 2666
2666 2667 raw
2667 2668 ---
2668 2669
2669 2670 Send raw data to the server.
2670 2671
2671 2672 The block payload contains the raw data to send as one atomic send
2672 2673 operation. The data may not actually be delivered in a single system
2673 2674 call: it depends on the abilities of the transport being used.
2674 2675
2675 2676 Each line in the block is de-indented and concatenated. Then, that
2676 2677 value is evaluated as a Python b'' literal. This allows the use of
2677 2678 backslash escaping, etc.
2678 2679
2679 2680 raw+
2680 2681 ----
2681 2682
2682 2683 Behaves like ``raw`` except flushes output afterwards.
2683 2684
2684 2685 command <X>
2685 2686 -----------
2686 2687
2687 2688 Send a request to run a named command, whose name follows the ``command``
2688 2689 string.
2689 2690
2690 2691 Arguments to the command are defined as lines in this block. The format of
2691 2692 each line is ``<key> <value>``. e.g.::
2692 2693
2693 2694 command listkeys
2694 2695 namespace bookmarks
2695 2696
2696 2697 If the value begins with ``eval:``, it will be interpreted as a Python
2697 2698 literal expression. Otherwise values are interpreted as Python b'' literals.
2698 2699 This allows sending complex types and encoding special byte sequences via
2699 2700 backslash escaping.
2700 2701
2701 2702 The following arguments have special meaning:
2702 2703
2703 2704 ``PUSHFILE``
2704 2705 When defined, the *push* mechanism of the peer will be used instead
2705 2706 of the static request-response mechanism and the content of the
2706 2707 file specified in the value of this argument will be sent as the
2707 2708 command payload.
2708 2709
2709 2710 This can be used to submit a local bundle file to the remote.
2710 2711
2711 2712 batchbegin
2712 2713 ----------
2713 2714
2714 2715 Instruct the peer to begin a batched send.
2715 2716
2716 2717 All ``command`` blocks are queued for execution until the next
2717 2718 ``batchsubmit`` block.
2718 2719
2719 2720 batchsubmit
2720 2721 -----------
2721 2722
2722 2723 Submit previously queued ``command`` blocks as a batch request.
2723 2724
2724 2725 This action MUST be paired with a ``batchbegin`` action.
2725 2726
2726 2727 httprequest <method> <path>
2727 2728 ---------------------------
2728 2729
2729 2730 (HTTP peer only)
2730 2731
2731 2732 Send an HTTP request to the peer.
2732 2733
2733 2734 The HTTP request line follows the ``httprequest`` action. e.g. ``GET /foo``.
2734 2735
2735 2736 Arguments of the form ``<key>: <value>`` are interpreted as HTTP request
2736 2737 headers to add to the request. e.g. ``Accept: foo``.
2737 2738
2738 2739 The following arguments are special:
2739 2740
2740 2741 ``BODYFILE``
2741 2742 The content of the file defined as the value to this argument will be
2742 2743 transferred verbatim as the HTTP request body.
2743 2744
2744 2745 ``frame <type> <flags> <payload>``
2745 2746 Send a unified protocol frame as part of the request body.
2746 2747
2747 2748 All frames will be collected and sent as the body to the HTTP
2748 2749 request.
2749 2750
2750 2751 close
2751 2752 -----
2752 2753
2753 2754 Close the connection to the server.
2754 2755
2755 2756 flush
2756 2757 -----
2757 2758
2758 2759 Flush data written to the server.
2759 2760
2760 2761 readavailable
2761 2762 -------------
2762 2763
2763 2764 Close the write end of the connection and read all available data from
2764 2765 the server.
2765 2766
2766 2767 If the connection to the server encompasses multiple pipes, we poll both
2767 2768 pipes and read available data.
2768 2769
2769 2770 readline
2770 2771 --------
2771 2772
2772 2773 Read a line of output from the server. If there are multiple output
2773 2774 pipes, reads only the main pipe.
2774 2775
2775 2776 ereadline
2776 2777 ---------
2777 2778
2778 2779 Like ``readline``, but read from the stderr pipe, if available.
2779 2780
2780 2781 read <X>
2781 2782 --------
2782 2783
2783 2784 ``read()`` N bytes from the server's main output pipe.
2784 2785
2785 2786 eread <X>
2786 2787 ---------
2787 2788
2788 2789 ``read()`` N bytes from the server's stderr pipe, if available.
2789 2790
2790 2791 Specifying Unified Frame-Based Protocol Frames
2791 2792 ----------------------------------------------
2792 2793
2793 2794 It is possible to emit a *Unified Frame-Based Protocol* by using special
2794 2795 syntax.
2795 2796
2796 2797 A frame is composed as a type, flags, and payload. These can be parsed
2797 2798 from a string of the form:
2798 2799
2799 2800 <request-id> <stream-id> <stream-flags> <type> <flags> <payload>
2800 2801
2801 2802 ``request-id`` and ``stream-id`` are integers defining the request and
2802 2803 stream identifiers.
2803 2804
2804 2805 ``type`` can be an integer value for the frame type or the string name
2805 2806 of the type. The strings are defined in ``wireprotoframing.py``. e.g.
2806 2807 ``command-name``.
2807 2808
2808 2809 ``stream-flags`` and ``flags`` are a ``|`` delimited list of flag
2809 2810 components. Each component (and there can be just one) can be an integer
2810 2811 or a flag name for stream flags or frame flags, respectively. Values are
2811 2812 resolved to integers and then bitwise OR'd together.
2812 2813
2813 2814 ``payload`` represents the raw frame payload. If it begins with
2814 2815 ``cbor:``, the following string is evaluated as Python code and the
2815 2816 resulting object is fed into a CBOR encoder. Otherwise it is interpreted
2816 2817 as a Python byte string literal.
2817 2818 """
2818 2819 opts = pycompat.byteskwargs(opts)
2819 2820
2820 2821 if opts['localssh'] and not repo:
2821 2822 raise error.Abort(_('--localssh requires a repository'))
2822 2823
2823 2824 if opts['peer'] and opts['peer'] not in ('raw', 'http2', 'ssh1', 'ssh2'):
2824 2825 raise error.Abort(_('invalid value for --peer'),
2825 2826 hint=_('valid values are "raw", "ssh1", and "ssh2"'))
2826 2827
2827 2828 if path and opts['localssh']:
2828 2829 raise error.Abort(_('cannot specify --localssh with an explicit '
2829 2830 'path'))
2830 2831
2831 2832 if ui.interactive():
2832 2833 ui.write(_('(waiting for commands on stdin)\n'))
2833 2834
2834 2835 blocks = list(_parsewirelangblocks(ui.fin))
2835 2836
2836 2837 proc = None
2837 2838 stdin = None
2838 2839 stdout = None
2839 2840 stderr = None
2840 2841 opener = None
2841 2842
2842 2843 if opts['localssh']:
2843 2844 # We start the SSH server in its own process so there is process
2844 2845 # separation. This prevents a whole class of potential bugs around
2845 2846 # shared state from interfering with server operation.
2846 2847 args = procutil.hgcmd() + [
2847 2848 '-R', repo.root,
2848 2849 'debugserve', '--sshstdio',
2849 2850 ]
2850 2851 proc = subprocess.Popen(args, stdin=subprocess.PIPE,
2851 2852 stdout=subprocess.PIPE, stderr=subprocess.PIPE,
2852 2853 bufsize=0)
2853 2854
2854 2855 stdin = proc.stdin
2855 2856 stdout = proc.stdout
2856 2857 stderr = proc.stderr
2857 2858
2858 2859 # We turn the pipes into observers so we can log I/O.
2859 2860 if ui.verbose or opts['peer'] == 'raw':
2860 2861 stdin = util.makeloggingfileobject(ui, proc.stdin, b'i',
2861 2862 logdata=True)
2862 2863 stdout = util.makeloggingfileobject(ui, proc.stdout, b'o',
2863 2864 logdata=True)
2864 2865 stderr = util.makeloggingfileobject(ui, proc.stderr, b'e',
2865 2866 logdata=True)
2866 2867
2867 2868 # --localssh also implies the peer connection settings.
2868 2869
2869 2870 url = 'ssh://localserver'
2870 2871 autoreadstderr = not opts['noreadstderr']
2871 2872
2872 2873 if opts['peer'] == 'ssh1':
2873 2874 ui.write(_('creating ssh peer for wire protocol version 1\n'))
2874 2875 peer = sshpeer.sshv1peer(ui, url, proc, stdin, stdout, stderr,
2875 2876 None, autoreadstderr=autoreadstderr)
2876 2877 elif opts['peer'] == 'ssh2':
2877 2878 ui.write(_('creating ssh peer for wire protocol version 2\n'))
2878 2879 peer = sshpeer.sshv2peer(ui, url, proc, stdin, stdout, stderr,
2879 2880 None, autoreadstderr=autoreadstderr)
2880 2881 elif opts['peer'] == 'raw':
2881 2882 ui.write(_('using raw connection to peer\n'))
2882 2883 peer = None
2883 2884 else:
2884 2885 ui.write(_('creating ssh peer from handshake results\n'))
2885 2886 peer = sshpeer.makepeer(ui, url, proc, stdin, stdout, stderr,
2886 2887 autoreadstderr=autoreadstderr)
2887 2888
2888 2889 elif path:
2889 2890 # We bypass hg.peer() so we can proxy the sockets.
2890 2891 # TODO consider not doing this because we skip
2891 2892 # ``hg.wirepeersetupfuncs`` and potentially other useful functionality.
2892 2893 u = util.url(path)
2893 2894 if u.scheme != 'http':
2894 2895 raise error.Abort(_('only http:// paths are currently supported'))
2895 2896
2896 2897 url, authinfo = u.authinfo()
2897 2898 openerargs = {
2898 2899 r'useragent': b'Mercurial debugwireproto',
2899 2900 }
2900 2901
2901 2902 # Turn pipes/sockets into observers so we can log I/O.
2902 2903 if ui.verbose:
2903 2904 openerargs.update({
2904 2905 r'loggingfh': ui,
2905 2906 r'loggingname': b's',
2906 2907 r'loggingopts': {
2907 2908 r'logdata': True,
2908 2909 r'logdataapis': False,
2909 2910 },
2910 2911 })
2911 2912
2912 2913 if ui.debugflag:
2913 2914 openerargs[r'loggingopts'][r'logdataapis'] = True
2914 2915
2915 2916 # Don't send default headers when in raw mode. This allows us to
2916 2917 # bypass most of the behavior of our URL handling code so we can
2917 2918 # have near complete control over what's sent on the wire.
2918 2919 if opts['peer'] == 'raw':
2919 2920 openerargs[r'sendaccept'] = False
2920 2921
2921 2922 opener = urlmod.opener(ui, authinfo, **openerargs)
2922 2923
2923 2924 if opts['peer'] == 'http2':
2924 2925 ui.write(_('creating http peer for wire protocol version 2\n'))
2925 2926 # We go through makepeer() because we need an API descriptor for
2926 2927 # the peer instance to be useful.
2927 2928 with ui.configoverride({
2928 2929 ('experimental', 'httppeer.advertise-v2'): True}):
2929 2930 if opts['nologhandshake']:
2930 2931 ui.pushbuffer()
2931 2932
2932 2933 peer = httppeer.makepeer(ui, path, opener=opener)
2933 2934
2934 2935 if opts['nologhandshake']:
2935 2936 ui.popbuffer()
2936 2937
2937 2938 if not isinstance(peer, httppeer.httpv2peer):
2938 2939 raise error.Abort(_('could not instantiate HTTP peer for '
2939 2940 'wire protocol version 2'),
2940 2941 hint=_('the server may not have the feature '
2941 2942 'enabled or is not allowing this '
2942 2943 'client version'))
2943 2944
2944 2945 elif opts['peer'] == 'raw':
2945 2946 ui.write(_('using raw connection to peer\n'))
2946 2947 peer = None
2947 2948 elif opts['peer']:
2948 2949 raise error.Abort(_('--peer %s not supported with HTTP peers') %
2949 2950 opts['peer'])
2950 2951 else:
2951 2952 peer = httppeer.makepeer(ui, path, opener=opener)
2952 2953
2953 2954 # We /could/ populate stdin/stdout with sock.makefile()...
2954 2955 else:
2955 2956 raise error.Abort(_('unsupported connection configuration'))
2956 2957
2957 2958 batchedcommands = None
2958 2959
2959 2960 # Now perform actions based on the parsed wire language instructions.
2960 2961 for action, lines in blocks:
2961 2962 if action in ('raw', 'raw+'):
2962 2963 if not stdin:
2963 2964 raise error.Abort(_('cannot call raw/raw+ on this peer'))
2964 2965
2965 2966 # Concatenate the data together.
2966 2967 data = ''.join(l.lstrip() for l in lines)
2967 2968 data = stringutil.unescapestr(data)
2968 2969 stdin.write(data)
2969 2970
2970 2971 if action == 'raw+':
2971 2972 stdin.flush()
2972 2973 elif action == 'flush':
2973 2974 if not stdin:
2974 2975 raise error.Abort(_('cannot call flush on this peer'))
2975 2976 stdin.flush()
2976 2977 elif action.startswith('command'):
2977 2978 if not peer:
2978 2979 raise error.Abort(_('cannot send commands unless peer instance '
2979 2980 'is available'))
2980 2981
2981 2982 command = action.split(' ', 1)[1]
2982 2983
2983 2984 args = {}
2984 2985 for line in lines:
2985 2986 # We need to allow empty values.
2986 2987 fields = line.lstrip().split(' ', 1)
2987 2988 if len(fields) == 1:
2988 2989 key = fields[0]
2989 2990 value = ''
2990 2991 else:
2991 2992 key, value = fields
2992 2993
2993 2994 if value.startswith('eval:'):
2994 2995 value = stringutil.evalpythonliteral(value[5:])
2995 2996 else:
2996 2997 value = stringutil.unescapestr(value)
2997 2998
2998 2999 args[key] = value
2999 3000
3000 3001 if batchedcommands is not None:
3001 3002 batchedcommands.append((command, args))
3002 3003 continue
3003 3004
3004 3005 ui.status(_('sending %s command\n') % command)
3005 3006
3006 3007 if 'PUSHFILE' in args:
3007 3008 with open(args['PUSHFILE'], r'rb') as fh:
3008 3009 del args['PUSHFILE']
3009 3010 res, output = peer._callpush(command, fh,
3010 3011 **pycompat.strkwargs(args))
3011 3012 ui.status(_('result: %s\n') % stringutil.escapestr(res))
3012 3013 ui.status(_('remote output: %s\n') %
3013 3014 stringutil.escapestr(output))
3014 3015 else:
3015 3016 with peer.commandexecutor() as e:
3016 3017 res = e.callcommand(command, args).result()
3017 3018
3018 3019 if isinstance(res, wireprotov2peer.commandresponse):
3019 3020 val = list(res.cborobjects())
3020 3021 ui.status(_('response: %s\n') % stringutil.pprint(val))
3021 3022
3022 3023 else:
3023 3024 ui.status(_('response: %s\n') % stringutil.pprint(res))
3024 3025
3025 3026 elif action == 'batchbegin':
3026 3027 if batchedcommands is not None:
3027 3028 raise error.Abort(_('nested batchbegin not allowed'))
3028 3029
3029 3030 batchedcommands = []
3030 3031 elif action == 'batchsubmit':
3031 3032 # There is a batching API we could go through. But it would be
3032 3033 # difficult to normalize requests into function calls. It is easier
3033 3034 # to bypass this layer and normalize to commands + args.
3034 3035 ui.status(_('sending batch with %d sub-commands\n') %
3035 3036 len(batchedcommands))
3036 3037 for i, chunk in enumerate(peer._submitbatch(batchedcommands)):
3037 3038 ui.status(_('response #%d: %s\n') %
3038 3039 (i, stringutil.escapestr(chunk)))
3039 3040
3040 3041 batchedcommands = None
3041 3042
3042 3043 elif action.startswith('httprequest '):
3043 3044 if not opener:
3044 3045 raise error.Abort(_('cannot use httprequest without an HTTP '
3045 3046 'peer'))
3046 3047
3047 3048 request = action.split(' ', 2)
3048 3049 if len(request) != 3:
3049 3050 raise error.Abort(_('invalid httprequest: expected format is '
3050 3051 '"httprequest <method> <path>'))
3051 3052
3052 3053 method, httppath = request[1:]
3053 3054 headers = {}
3054 3055 body = None
3055 3056 frames = []
3056 3057 for line in lines:
3057 3058 line = line.lstrip()
3058 3059 m = re.match(b'^([a-zA-Z0-9_-]+): (.*)$', line)
3059 3060 if m:
3060 3061 headers[m.group(1)] = m.group(2)
3061 3062 continue
3062 3063
3063 3064 if line.startswith(b'BODYFILE '):
3064 3065 with open(line.split(b' ', 1), 'rb') as fh:
3065 3066 body = fh.read()
3066 3067 elif line.startswith(b'frame '):
3067 3068 frame = wireprotoframing.makeframefromhumanstring(
3068 3069 line[len(b'frame '):])
3069 3070
3070 3071 frames.append(frame)
3071 3072 else:
3072 3073 raise error.Abort(_('unknown argument to httprequest: %s') %
3073 3074 line)
3074 3075
3075 3076 url = path + httppath
3076 3077
3077 3078 if frames:
3078 3079 body = b''.join(bytes(f) for f in frames)
3079 3080
3080 3081 req = urlmod.urlreq.request(pycompat.strurl(url), body, headers)
3081 3082
3082 3083 # urllib.Request insists on using has_data() as a proxy for
3083 3084 # determining the request method. Override that to use our
3084 3085 # explicitly requested method.
3085 3086 req.get_method = lambda: method
3086 3087
3087 3088 try:
3088 3089 res = opener.open(req)
3089 3090 body = res.read()
3090 3091 except util.urlerr.urlerror as e:
3091 3092 e.read()
3092 3093 continue
3093 3094
3094 3095 if res.headers.get('Content-Type') == 'application/mercurial-cbor':
3095 3096 ui.write(_('cbor> %s\n') % stringutil.pprint(cbor.loads(body)))
3096 3097
3097 3098 elif action == 'close':
3098 3099 peer.close()
3099 3100 elif action == 'readavailable':
3100 3101 if not stdout or not stderr:
3101 3102 raise error.Abort(_('readavailable not available on this peer'))
3102 3103
3103 3104 stdin.close()
3104 3105 stdout.read()
3105 3106 stderr.read()
3106 3107
3107 3108 elif action == 'readline':
3108 3109 if not stdout:
3109 3110 raise error.Abort(_('readline not available on this peer'))
3110 3111 stdout.readline()
3111 3112 elif action == 'ereadline':
3112 3113 if not stderr:
3113 3114 raise error.Abort(_('ereadline not available on this peer'))
3114 3115 stderr.readline()
3115 3116 elif action.startswith('read '):
3116 3117 count = int(action.split(' ', 1)[1])
3117 3118 if not stdout:
3118 3119 raise error.Abort(_('read not available on this peer'))
3119 3120 stdout.read(count)
3120 3121 elif action.startswith('eread '):
3121 3122 count = int(action.split(' ', 1)[1])
3122 3123 if not stderr:
3123 3124 raise error.Abort(_('eread not available on this peer'))
3124 3125 stderr.read(count)
3125 3126 else:
3126 3127 raise error.Abort(_('unknown action: %s') % action)
3127 3128
3128 3129 if batchedcommands is not None:
3129 3130 raise error.Abort(_('unclosed "batchbegin" request'))
3130 3131
3131 3132 if peer:
3132 3133 peer.close()
3133 3134
3134 3135 if proc:
3135 3136 proc.kill()
@@ -1,290 +1,290 b''
1 1 $ cat >> $HGRCPATH <<EOF
2 2 > [experimental]
3 3 > bundle-phases=yes
4 4 > [extensions]
5 5 > strip=
6 6 > drawdag=$TESTDIR/drawdag.py
7 7 > EOF
8 8
9 9 Set up repo with linear history
10 10 $ hg init linear
11 11 $ cd linear
12 12 $ hg debugdrawdag <<'EOF'
13 13 > E
14 14 > |
15 15 > D
16 16 > |
17 17 > C
18 18 > |
19 19 > B
20 20 > |
21 21 > A
22 22 > EOF
23 23 $ hg phase --public A
24 24 $ hg phase --force --secret D
25 25 $ hg log -G -T '{desc} {phase}\n'
26 26 o E secret
27 27 |
28 28 o D secret
29 29 |
30 30 o C draft
31 31 |
32 32 o B draft
33 33 |
34 34 o A public
35 35
36 36 Phases are restored when unbundling
37 37 $ hg bundle --base B -r E bundle
38 38 3 changesets found
39 39 $ hg debugbundle bundle
40 40 Stream params: {Compression: BZ}
41 changegroup -- {nbchanges: 3, targetphase: 2, version: 02}
41 changegroup -- {nbchanges: 3, targetphase: 2, version: 02} (mandatory: True)
42 42 26805aba1e600a82e93661149f2313866a221a7b
43 43 f585351a92f85104bff7c284233c338b10eb1df7
44 44 9bc730a19041f9ec7cb33c626e811aa233efb18c
45 cache:rev-branch-cache -- {}
46 phase-heads -- {}
45 cache:rev-branch-cache -- {} (mandatory: True)
46 phase-heads -- {} (mandatory: True)
47 47 26805aba1e600a82e93661149f2313866a221a7b draft
48 48 $ hg strip --no-backup C
49 49 $ hg unbundle -q bundle
50 50 $ rm bundle
51 51 $ hg log -G -T '{desc} {phase}\n'
52 52 o E secret
53 53 |
54 54 o D secret
55 55 |
56 56 o C draft
57 57 |
58 58 o B draft
59 59 |
60 60 o A public
61 61
62 62 Root revision's phase is preserved
63 63 $ hg bundle -a bundle
64 64 5 changesets found
65 65 $ hg strip --no-backup A
66 66 $ hg unbundle -q bundle
67 67 $ rm bundle
68 68 $ hg log -G -T '{desc} {phase}\n'
69 69 o E secret
70 70 |
71 71 o D secret
72 72 |
73 73 o C draft
74 74 |
75 75 o B draft
76 76 |
77 77 o A public
78 78
79 79 Completely public history can be restored
80 80 $ hg phase --public E
81 81 $ hg bundle -a bundle
82 82 5 changesets found
83 83 $ hg strip --no-backup A
84 84 $ hg unbundle -q bundle
85 85 $ rm bundle
86 86 $ hg log -G -T '{desc} {phase}\n'
87 87 o E public
88 88 |
89 89 o D public
90 90 |
91 91 o C public
92 92 |
93 93 o B public
94 94 |
95 95 o A public
96 96
97 97 Direct transition from public to secret can be restored
98 98 $ hg phase --secret --force D
99 99 $ hg bundle -a bundle
100 100 5 changesets found
101 101 $ hg strip --no-backup A
102 102 $ hg unbundle -q bundle
103 103 $ rm bundle
104 104 $ hg log -G -T '{desc} {phase}\n'
105 105 o E secret
106 106 |
107 107 o D secret
108 108 |
109 109 o C public
110 110 |
111 111 o B public
112 112 |
113 113 o A public
114 114
115 115 Revisions within bundle preserve their phase even if parent changes its phase
116 116 $ hg phase --draft --force B
117 117 $ hg bundle --base B -r E bundle
118 118 3 changesets found
119 119 $ hg strip --no-backup C
120 120 $ hg phase --public B
121 121 $ hg unbundle -q bundle
122 122 $ rm bundle
123 123 $ hg log -G -T '{desc} {phase}\n'
124 124 o E secret
125 125 |
126 126 o D secret
127 127 |
128 128 o C draft
129 129 |
130 130 o B public
131 131 |
132 132 o A public
133 133
134 134 Phase of ancestors of stripped node get advanced to accommodate child
135 135 $ hg bundle --base B -r E bundle
136 136 3 changesets found
137 137 $ hg strip --no-backup C
138 138 $ hg phase --force --secret B
139 139 $ hg unbundle -q bundle
140 140 $ rm bundle
141 141 $ hg log -G -T '{desc} {phase}\n'
142 142 o E secret
143 143 |
144 144 o D secret
145 145 |
146 146 o C draft
147 147 |
148 148 o B draft
149 149 |
150 150 o A public
151 151
152 152 Unbundling advances phases of changesets even if they were already in the repo.
153 153 To test that, create a bundle of everything in draft phase and then unbundle
154 154 to see that secret becomes draft, but public remains public.
155 155 $ hg phase --draft --force A
156 156 $ hg phase --draft E
157 157 $ hg bundle -a bundle
158 158 5 changesets found
159 159 $ hg phase --public A
160 160 $ hg phase --secret --force E
161 161 $ hg unbundle -q bundle
162 162 $ rm bundle
163 163 $ hg log -G -T '{desc} {phase}\n'
164 164 o E draft
165 165 |
166 166 o D draft
167 167 |
168 168 o C draft
169 169 |
170 170 o B draft
171 171 |
172 172 o A public
173 173
174 174 Unbundling change in the middle of a stack does not affect later changes
175 175 $ hg strip --no-backup E
176 176 $ hg phase --secret --force D
177 177 $ hg log -G -T '{desc} {phase}\n'
178 178 o D secret
179 179 |
180 180 o C draft
181 181 |
182 182 o B draft
183 183 |
184 184 o A public
185 185
186 186 $ hg bundle --base A -r B bundle
187 187 1 changesets found
188 188 $ hg unbundle -q bundle
189 189 $ rm bundle
190 190 $ hg log -G -T '{desc} {phase}\n'
191 191 o D secret
192 192 |
193 193 o C draft
194 194 |
195 195 o B draft
196 196 |
197 197 o A public
198 198
199 199
200 200 $ cd ..
201 201
202 202 Set up repo with non-linear history
203 203 $ hg init non-linear
204 204 $ cd non-linear
205 205 $ hg debugdrawdag <<'EOF'
206 206 > D E
207 207 > |\|
208 208 > B C
209 209 > |/
210 210 > A
211 211 > EOF
212 212 $ hg phase --public C
213 213 $ hg phase --force --secret B
214 214 $ hg log -G -T '{node|short} {desc} {phase}\n'
215 215 o 03ca77807e91 E draft
216 216 |
217 217 | o 4e4f9194f9f1 D secret
218 218 |/|
219 219 o | dc0947a82db8 C public
220 220 | |
221 221 | o 112478962961 B secret
222 222 |/
223 223 o 426bada5c675 A public
224 224
225 225
226 226 Restore bundle of entire repo
227 227 $ hg bundle -a bundle
228 228 5 changesets found
229 229 $ hg debugbundle bundle
230 230 Stream params: {Compression: BZ}
231 changegroup -- {nbchanges: 5, targetphase: 2, version: 02}
231 changegroup -- {nbchanges: 5, targetphase: 2, version: 02} (mandatory: True)
232 232 426bada5c67598ca65036d57d9e4b64b0c1ce7a0
233 233 112478962961147124edd43549aedd1a335e44bf
234 234 dc0947a82db884575bb76ea10ac97b08536bfa03
235 235 4e4f9194f9f181c57f62e823e8bdfa46ab9e4ff4
236 236 03ca77807e919db8807c3749086dc36fb478cac0
237 cache:rev-branch-cache -- {}
238 phase-heads -- {}
237 cache:rev-branch-cache -- {} (mandatory: True)
238 phase-heads -- {} (mandatory: True)
239 239 dc0947a82db884575bb76ea10ac97b08536bfa03 public
240 240 03ca77807e919db8807c3749086dc36fb478cac0 draft
241 241 $ hg strip --no-backup A
242 242 $ hg unbundle -q bundle
243 243 $ rm bundle
244 244 $ hg log -G -T '{node|short} {desc} {phase}\n'
245 245 o 03ca77807e91 E draft
246 246 |
247 247 | o 4e4f9194f9f1 D secret
248 248 |/|
249 249 o | dc0947a82db8 C public
250 250 | |
251 251 | o 112478962961 B secret
252 252 |/
253 253 o 426bada5c675 A public
254 254
255 255
256 256 $ hg bundle --base 'A + C' -r D bundle
257 257 2 changesets found
258 258 $ hg debugbundle bundle
259 259 Stream params: {Compression: BZ}
260 changegroup -- {nbchanges: 2, targetphase: 2, version: 02}
260 changegroup -- {nbchanges: 2, targetphase: 2, version: 02} (mandatory: True)
261 261 112478962961147124edd43549aedd1a335e44bf
262 262 4e4f9194f9f181c57f62e823e8bdfa46ab9e4ff4
263 cache:rev-branch-cache -- {}
264 phase-heads -- {}
263 cache:rev-branch-cache -- {} (mandatory: True)
264 phase-heads -- {} (mandatory: True)
265 265 $ rm bundle
266 266
267 267 $ hg bundle --base A -r D bundle
268 268 3 changesets found
269 269 $ hg debugbundle bundle
270 270 Stream params: {Compression: BZ}
271 changegroup -- {nbchanges: 3, targetphase: 2, version: 02}
271 changegroup -- {nbchanges: 3, targetphase: 2, version: 02} (mandatory: True)
272 272 112478962961147124edd43549aedd1a335e44bf
273 273 dc0947a82db884575bb76ea10ac97b08536bfa03
274 274 4e4f9194f9f181c57f62e823e8bdfa46ab9e4ff4
275 cache:rev-branch-cache -- {}
276 phase-heads -- {}
275 cache:rev-branch-cache -- {} (mandatory: True)
276 phase-heads -- {} (mandatory: True)
277 277 dc0947a82db884575bb76ea10ac97b08536bfa03 public
278 278 $ rm bundle
279 279
280 280 $ hg bundle --base 'B + C' -r 'D + E' bundle
281 281 2 changesets found
282 282 $ hg debugbundle bundle
283 283 Stream params: {Compression: BZ}
284 changegroup -- {nbchanges: 2, targetphase: 2, version: 02}
284 changegroup -- {nbchanges: 2, targetphase: 2, version: 02} (mandatory: True)
285 285 4e4f9194f9f181c57f62e823e8bdfa46ab9e4ff4
286 286 03ca77807e919db8807c3749086dc36fb478cac0
287 cache:rev-branch-cache -- {}
288 phase-heads -- {}
287 cache:rev-branch-cache -- {} (mandatory: True)
288 phase-heads -- {} (mandatory: True)
289 289 03ca77807e919db8807c3749086dc36fb478cac0 draft
290 290 $ rm bundle
@@ -1,232 +1,232 b''
1 1 bundle w/o type option
2 2
3 3 $ hg init t1
4 4 $ hg init t2
5 5 $ cd t1
6 6 $ echo blablablablabla > file.txt
7 7 $ hg ci -Ama
8 8 adding file.txt
9 9 $ hg log | grep summary
10 10 summary: a
11 11 $ hg bundle ../b1 ../t2
12 12 searching for changes
13 13 1 changesets found
14 14
15 15 $ cd ../t2
16 16 $ hg unbundle ../b1
17 17 adding changesets
18 18 adding manifests
19 19 adding file changes
20 20 added 1 changesets with 1 changes to 1 files
21 21 new changesets c35a0f9217e6
22 22 (run 'hg update' to get a working copy)
23 23 $ hg up
24 24 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
25 25 $ hg log | grep summary
26 26 summary: a
27 27 $ cd ..
28 28
29 29 Unknown compression type is rejected
30 30
31 31 $ hg init t3
32 32 $ cd t3
33 33 $ hg -q unbundle ../b1
34 34 $ hg bundle -a -t unknown out.hg
35 35 abort: unknown is not a recognized bundle specification
36 36 (see 'hg help bundlespec' for supported values for --type)
37 37 [255]
38 38
39 39 $ hg bundle -a -t unknown-v2 out.hg
40 40 abort: unknown compression is not supported
41 41 (see 'hg help bundlespec' for supported values for --type)
42 42 [255]
43 43
44 44 $ cd ..
45 45
46 46 test bundle types
47 47
48 48 $ testbundle() {
49 49 > echo % test bundle type $1
50 50 > hg init t$1
51 51 > cd t1
52 52 > hg bundle -t $1 ../b$1 ../t$1
53 53 > f -q -B6 -D ../b$1; echo
54 54 > cd ../t$1
55 55 > hg debugbundle ../b$1
56 56 > hg debugbundle --spec ../b$1
57 57 > echo
58 58 > cd ..
59 59 > }
60 60
61 61 $ for t in "None" "bzip2" "gzip" "none-v2" "v2" "v1" "gzip-v1"; do
62 62 > testbundle $t
63 63 > done
64 64 % test bundle type None
65 65 searching for changes
66 66 1 changesets found
67 67 HG20\x00\x00 (esc)
68 68 Stream params: {}
69 changegroup -- {nbchanges: 1, version: 02}
69 changegroup -- {nbchanges: 1, version: 02} (mandatory: True)
70 70 c35a0f9217e65d1fdb90c936ffa7dbe679f83ddf
71 cache:rev-branch-cache -- {}
71 cache:rev-branch-cache -- {} (mandatory: True)
72 72 none-v2
73 73
74 74 % test bundle type bzip2
75 75 searching for changes
76 76 1 changesets found
77 77 HG20\x00\x00 (esc)
78 78 Stream params: {Compression: BZ}
79 changegroup -- {nbchanges: 1, version: 02}
79 changegroup -- {nbchanges: 1, version: 02} (mandatory: True)
80 80 c35a0f9217e65d1fdb90c936ffa7dbe679f83ddf
81 cache:rev-branch-cache -- {}
81 cache:rev-branch-cache -- {} (mandatory: True)
82 82 bzip2-v2
83 83
84 84 % test bundle type gzip
85 85 searching for changes
86 86 1 changesets found
87 87 HG20\x00\x00 (esc)
88 88 Stream params: {Compression: GZ}
89 changegroup -- {nbchanges: 1, version: 02}
89 changegroup -- {nbchanges: 1, version: 02} (mandatory: True)
90 90 c35a0f9217e65d1fdb90c936ffa7dbe679f83ddf
91 cache:rev-branch-cache -- {}
91 cache:rev-branch-cache -- {} (mandatory: True)
92 92 gzip-v2
93 93
94 94 % test bundle type none-v2
95 95 searching for changes
96 96 1 changesets found
97 97 HG20\x00\x00 (esc)
98 98 Stream params: {}
99 changegroup -- {nbchanges: 1, version: 02}
99 changegroup -- {nbchanges: 1, version: 02} (mandatory: True)
100 100 c35a0f9217e65d1fdb90c936ffa7dbe679f83ddf
101 cache:rev-branch-cache -- {}
101 cache:rev-branch-cache -- {} (mandatory: True)
102 102 none-v2
103 103
104 104 % test bundle type v2
105 105 searching for changes
106 106 1 changesets found
107 107 HG20\x00\x00 (esc)
108 108 Stream params: {Compression: BZ}
109 changegroup -- {nbchanges: 1, version: 02}
109 changegroup -- {nbchanges: 1, version: 02} (mandatory: True)
110 110 c35a0f9217e65d1fdb90c936ffa7dbe679f83ddf
111 cache:rev-branch-cache -- {}
111 cache:rev-branch-cache -- {} (mandatory: True)
112 112 bzip2-v2
113 113
114 114 % test bundle type v1
115 115 searching for changes
116 116 1 changesets found
117 117 HG10BZ
118 118 c35a0f9217e65d1fdb90c936ffa7dbe679f83ddf
119 119 bzip2-v1
120 120
121 121 % test bundle type gzip-v1
122 122 searching for changes
123 123 1 changesets found
124 124 HG10GZ
125 125 c35a0f9217e65d1fdb90c936ffa7dbe679f83ddf
126 126 gzip-v1
127 127
128 128
129 129 Compression level can be adjusted for bundle2 bundles
130 130
131 131 $ hg init test-complevel
132 132 $ cd test-complevel
133 133
134 134 $ cat > file0 << EOF
135 135 > this is a file
136 136 > with some text
137 137 > and some more text
138 138 > and other content
139 139 > EOF
140 140 $ cat > file1 << EOF
141 141 > this is another file
142 142 > with some other content
143 143 > and repeated, repeated, repeated, repeated content
144 144 > EOF
145 145 $ hg -q commit -A -m initial
146 146
147 147 $ hg bundle -a -t gzip-v2 gzip-v2.hg
148 148 1 changesets found
149 149 $ f --size gzip-v2.hg
150 150 gzip-v2.hg: size=468
151 151
152 152 $ hg --config experimental.bundlecomplevel=1 bundle -a -t gzip-v2 gzip-v2-level1.hg
153 153 1 changesets found
154 154 $ f --size gzip-v2-level1.hg
155 155 gzip-v2-level1.hg: size=475
156 156
157 157 $ hg --config experimental.bundlecomplevel.gzip=1 --config experimental.bundlelevel=9 bundle -a -t gzip-v2 gzip-v2-level1.hg
158 158 1 changesets found
159 159 $ f --size gzip-v2-level1.hg
160 160 gzip-v2-level1.hg: size=475
161 161
162 162 $ cd ..
163 163
164 164 #if zstd
165 165
166 166 $ for t in "zstd" "zstd-v2"; do
167 167 > testbundle $t
168 168 > done
169 169 % test bundle type zstd
170 170 searching for changes
171 171 1 changesets found
172 172 HG20\x00\x00 (esc)
173 173 Stream params: {Compression: ZS}
174 changegroup -- {nbchanges: 1, version: 02}
174 changegroup -- {nbchanges: 1, version: 02} (mandatory: True)
175 175 c35a0f9217e65d1fdb90c936ffa7dbe679f83ddf
176 cache:rev-branch-cache -- {}
176 cache:rev-branch-cache -- {} (mandatory: True)
177 177 zstd-v2
178 178
179 179 % test bundle type zstd-v2
180 180 searching for changes
181 181 1 changesets found
182 182 HG20\x00\x00 (esc)
183 183 Stream params: {Compression: ZS}
184 changegroup -- {nbchanges: 1, version: 02}
184 changegroup -- {nbchanges: 1, version: 02} (mandatory: True)
185 185 c35a0f9217e65d1fdb90c936ffa7dbe679f83ddf
186 cache:rev-branch-cache -- {}
186 cache:rev-branch-cache -- {} (mandatory: True)
187 187 zstd-v2
188 188
189 189
190 190 Explicit request for zstd on non-generaldelta repos
191 191
192 192 $ hg --config format.usegeneraldelta=false init nogd
193 193 $ hg -q -R nogd pull t1
194 194 $ hg -R nogd bundle -a -t zstd nogd-zstd
195 195 1 changesets found
196 196
197 197 zstd-v1 always fails
198 198
199 199 $ hg -R tzstd bundle -a -t zstd-v1 zstd-v1
200 200 abort: compression engine zstd is not supported on v1 bundles
201 201 (see 'hg help bundlespec' for supported values for --type)
202 202 [255]
203 203
204 204 #else
205 205
206 206 zstd is a valid engine but isn't available
207 207
208 208 $ hg -R t1 bundle -a -t zstd irrelevant.hg
209 209 abort: compression engine zstd could not be loaded
210 210 [255]
211 211
212 212 #endif
213 213
214 214 test garbage file
215 215
216 216 $ echo garbage > bgarbage
217 217 $ hg init tgarbage
218 218 $ cd tgarbage
219 219 $ hg pull ../bgarbage
220 220 pulling from ../bgarbage
221 221 abort: ../bgarbage: not a Mercurial bundle
222 222 [255]
223 223 $ cd ..
224 224
225 225 test invalid bundle type
226 226
227 227 $ cd t1
228 228 $ hg bundle -a -t garbage ../bgarbage
229 229 abort: garbage is not a recognized bundle specification
230 230 (see 'hg help bundlespec' for supported values for --type)
231 231 [255]
232 232 $ cd ..
@@ -1,1236 +1,1236 b''
1 1 This test is dedicated to test the bundle2 container format
2 2
3 3 It test multiple existing parts to test different feature of the container. You
4 4 probably do not need to touch this test unless you change the binary encoding
5 5 of the bundle2 format itself.
6 6
7 7 Create an extension to test bundle2 API
8 8
9 9 $ cat > bundle2.py << EOF
10 10 > """A small extension to test bundle2 implementation
11 11 >
12 12 > This extension allows detailed testing of the various bundle2 API and
13 13 > behaviors.
14 14 > """
15 15 > import gc
16 16 > import os
17 17 > import sys
18 18 > from mercurial import util
19 19 > from mercurial import bundle2
20 20 > from mercurial import scmutil
21 21 > from mercurial import discovery
22 22 > from mercurial import changegroup
23 23 > from mercurial import error
24 24 > from mercurial import obsolete
25 25 > from mercurial import pycompat
26 26 > from mercurial import registrar
27 27 >
28 28 >
29 29 > try:
30 30 > import msvcrt
31 31 > msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
32 32 > msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
33 33 > msvcrt.setmode(sys.stderr.fileno(), os.O_BINARY)
34 34 > except ImportError:
35 35 > pass
36 36 >
37 37 > cmdtable = {}
38 38 > command = registrar.command(cmdtable)
39 39 >
40 40 > ELEPHANTSSONG = b"""Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
41 41 > Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
42 42 > Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko."""
43 43 > assert len(ELEPHANTSSONG) == 178 # future test say 178 bytes, trust it.
44 44 >
45 45 > @bundle2.parthandler(b'test:song')
46 46 > def songhandler(op, part):
47 47 > """handle a "test:song" bundle2 part, printing the lyrics on stdin"""
48 48 > op.ui.write(b'The choir starts singing:\n')
49 49 > verses = 0
50 50 > for line in part.read().split(b'\n'):
51 51 > op.ui.write(b' %s\n' % line)
52 52 > verses += 1
53 53 > op.records.add(b'song', {b'verses': verses})
54 54 >
55 55 > @bundle2.parthandler(b'test:ping')
56 56 > def pinghandler(op, part):
57 57 > op.ui.write(b'received ping request (id %i)\n' % part.id)
58 58 > if op.reply is not None and b'ping-pong' in op.reply.capabilities:
59 59 > op.ui.write_err(b'replying to ping request (id %i)\n' % part.id)
60 60 > op.reply.newpart(b'test:pong', [(b'in-reply-to', b'%d' % part.id)],
61 61 > mandatory=False)
62 62 >
63 63 > @bundle2.parthandler(b'test:debugreply')
64 64 > def debugreply(op, part):
65 65 > """print data about the capacity of the bundle reply"""
66 66 > if op.reply is None:
67 67 > op.ui.write(b'debugreply: no reply\n')
68 68 > else:
69 69 > op.ui.write(b'debugreply: capabilities:\n')
70 70 > for cap in sorted(op.reply.capabilities):
71 71 > op.ui.write(b"debugreply: '%s'\n" % cap)
72 72 > for val in op.reply.capabilities[cap]:
73 73 > op.ui.write(b"debugreply: '%s'\n" % val)
74 74 >
75 75 > @command(b'bundle2',
76 76 > [(b'', b'param', [], b'stream level parameter'),
77 77 > (b'', b'unknown', False, b'include an unknown mandatory part in the bundle'),
78 78 > (b'', b'unknownparams', False, b'include an unknown part parameters in the bundle'),
79 79 > (b'', b'parts', False, b'include some arbitrary parts to the bundle'),
80 80 > (b'', b'reply', False, b'produce a reply bundle'),
81 81 > (b'', b'pushrace', False, b'includes a check:head part with unknown nodes'),
82 82 > (b'', b'genraise', False, b'includes a part that raise an exception during generation'),
83 83 > (b'', b'timeout', False, b'emulate a timeout during bundle generation'),
84 84 > (b'r', b'rev', [], b'includes those changeset in the bundle'),
85 85 > (b'', b'compress', b'', b'compress the stream'),],
86 86 > b'[OUTPUTFILE]')
87 87 > def cmdbundle2(ui, repo, path=None, **opts):
88 88 > """write a bundle2 container on standard output"""
89 89 > bundler = bundle2.bundle20(ui)
90 90 > for p in opts['param']:
91 91 > p = p.split(b'=', 1)
92 92 > try:
93 93 > bundler.addparam(*p)
94 94 > except ValueError as exc:
95 95 > raise error.Abort('%s' % exc)
96 96 >
97 97 > if opts['compress']:
98 98 > bundler.setcompression(opts['compress'])
99 99 >
100 100 > if opts['reply']:
101 101 > capsstring = b'ping-pong\nelephants=babar,celeste\ncity%3D%21=celeste%2Cville'
102 102 > bundler.newpart(b'replycaps', data=capsstring)
103 103 >
104 104 > if opts['pushrace']:
105 105 > # also serve to test the assignement of data outside of init
106 106 > part = bundler.newpart(b'check:heads')
107 107 > part.data = b'01234567890123456789'
108 108 >
109 109 > revs = opts['rev']
110 110 > if 'rev' in opts:
111 111 > revs = scmutil.revrange(repo, opts['rev'])
112 112 > if revs:
113 113 > # very crude version of a changegroup part creation
114 114 > bundled = repo.revs('%ld::%ld', revs, revs)
115 115 > headmissing = [c.node() for c in repo.set('heads(%ld)', revs)]
116 116 > headcommon = [c.node() for c in repo.set('parents(%ld) - %ld', revs, revs)]
117 117 > outgoing = discovery.outgoing(repo, headcommon, headmissing)
118 118 > cg = changegroup.makechangegroup(repo, outgoing, b'01',
119 119 > b'test:bundle2')
120 120 > bundler.newpart(b'changegroup', data=cg.getchunks(),
121 121 > mandatory=False)
122 122 >
123 123 > if opts['parts']:
124 124 > bundler.newpart(b'test:empty', mandatory=False)
125 125 > # add a second one to make sure we handle multiple parts
126 126 > bundler.newpart(b'test:empty', mandatory=False)
127 127 > bundler.newpart(b'test:song', data=ELEPHANTSSONG, mandatory=False)
128 128 > bundler.newpart(b'test:debugreply', mandatory=False)
129 129 > mathpart = bundler.newpart(b'test:math')
130 130 > mathpart.addparam(b'pi', b'3.14')
131 131 > mathpart.addparam(b'e', b'2.72')
132 132 > mathpart.addparam(b'cooking', b'raw', mandatory=False)
133 133 > mathpart.data = b'42'
134 134 > mathpart.mandatory = False
135 135 > # advisory known part with unknown mandatory param
136 136 > bundler.newpart(b'test:song', [(b'randomparam', b'')], mandatory=False)
137 137 > if opts['unknown']:
138 138 > bundler.newpart(b'test:unknown', data=b'some random content')
139 139 > if opts['unknownparams']:
140 140 > bundler.newpart(b'test:song', [(b'randomparams', b'')])
141 141 > if opts['parts']:
142 142 > bundler.newpart(b'test:ping', mandatory=False)
143 143 > if opts['genraise']:
144 144 > def genraise():
145 145 > yield b'first line\n'
146 146 > raise RuntimeError('Someone set up us the bomb!')
147 147 > bundler.newpart(b'output', data=genraise(), mandatory=False)
148 148 >
149 149 > if path is None:
150 150 > file = pycompat.stdout
151 151 > else:
152 152 > file = open(path, 'wb')
153 153 >
154 154 > if opts['timeout']:
155 155 > bundler.newpart(b'test:song', data=ELEPHANTSSONG, mandatory=False)
156 156 > for idx, junk in enumerate(bundler.getchunks()):
157 157 > ui.write(b'%d chunk\n' % idx)
158 158 > if idx > 4:
159 159 > # This throws a GeneratorExit inside the generator, which
160 160 > # can cause problems if the exception-recovery code is
161 161 > # too zealous. It's important for this test that the break
162 162 > # occur while we're in the middle of a part.
163 163 > break
164 164 > gc.collect()
165 165 > ui.write(b'fake timeout complete.\n')
166 166 > return
167 167 > try:
168 168 > for chunk in bundler.getchunks():
169 169 > file.write(chunk)
170 170 > except RuntimeError as exc:
171 171 > raise error.Abort(exc)
172 172 > finally:
173 173 > file.flush()
174 174 >
175 175 > @command(b'unbundle2', [], b'')
176 176 > def cmdunbundle2(ui, repo, replypath=None):
177 177 > """process a bundle2 stream from stdin on the current repo"""
178 178 > try:
179 179 > tr = None
180 180 > lock = repo.lock()
181 181 > tr = repo.transaction(b'processbundle')
182 182 > try:
183 183 > unbundler = bundle2.getunbundler(ui, pycompat.stdin)
184 184 > op = bundle2.processbundle(repo, unbundler, lambda: tr)
185 185 > tr.close()
186 186 > except error.BundleValueError as exc:
187 187 > raise error.Abort('missing support for %s' % exc)
188 188 > except error.PushRaced as exc:
189 189 > raise error.Abort('push race: %s' % exc)
190 190 > finally:
191 191 > if tr is not None:
192 192 > tr.release()
193 193 > lock.release()
194 194 > remains = pycompat.stdin.read()
195 195 > ui.write(b'%i unread bytes\n' % len(remains))
196 196 > if op.records[b'song']:
197 197 > totalverses = sum(r[b'verses'] for r in op.records[b'song'])
198 198 > ui.write(b'%i total verses sung\n' % totalverses)
199 199 > for rec in op.records[b'changegroup']:
200 200 > ui.write(b'addchangegroup return: %i\n' % rec[b'return'])
201 201 > if op.reply is not None and replypath is not None:
202 202 > with open(replypath, 'wb') as file:
203 203 > for chunk in op.reply.getchunks():
204 204 > file.write(chunk)
205 205 >
206 206 > @command(b'statbundle2', [], b'')
207 207 > def cmdstatbundle2(ui, repo):
208 208 > """print statistic on the bundle2 container read from stdin"""
209 209 > unbundler = bundle2.getunbundler(ui, pycompat.stdin)
210 210 > try:
211 211 > params = unbundler.params
212 212 > except error.BundleValueError as exc:
213 213 > raise error.Abort(b'unknown parameters: %s' % exc)
214 214 > ui.write(b'options count: %i\n' % len(params))
215 215 > for key in sorted(params):
216 216 > ui.write(b'- %s\n' % key)
217 217 > value = params[key]
218 218 > if value is not None:
219 219 > ui.write(b' %s\n' % value)
220 220 > count = 0
221 221 > for p in unbundler.iterparts():
222 222 > count += 1
223 223 > ui.write(b' :%s:\n' % p.type)
224 224 > ui.write(b' mandatory: %i\n' % len(p.mandatoryparams))
225 225 > ui.write(b' advisory: %i\n' % len(p.advisoryparams))
226 226 > ui.write(b' payload: %i bytes\n' % len(p.read()))
227 227 > ui.write(b'parts count: %i\n' % count)
228 228 > EOF
229 229 $ cat >> $HGRCPATH << EOF
230 230 > [extensions]
231 231 > bundle2=$TESTTMP/bundle2.py
232 232 > [experimental]
233 233 > evolution.createmarkers=True
234 234 > [ui]
235 235 > ssh=$PYTHON "$TESTDIR/dummyssh"
236 236 > logtemplate={rev}:{node|short} {phase} {author} {bookmarks} {desc|firstline}
237 237 > [web]
238 238 > push_ssl = false
239 239 > allow_push = *
240 240 > [phases]
241 241 > publish=False
242 242 > EOF
243 243
244 244 The extension requires a repo (currently unused)
245 245
246 246 $ hg init main
247 247 $ cd main
248 248 $ touch a
249 249 $ hg add a
250 250 $ hg commit -m 'a'
251 251
252 252
253 253 Empty bundle
254 254 =================
255 255
256 256 - no option
257 257 - no parts
258 258
259 259 Test bundling
260 260
261 261 $ hg bundle2 | f --hexdump
262 262
263 263 0000: 48 47 32 30 00 00 00 00 00 00 00 00 |HG20........|
264 264
265 265 Test timeouts during bundling
266 266 $ hg bundle2 --timeout --debug --config devel.bundle2.debug=yes
267 267 bundle2-output-bundle: "HG20", 1 parts total
268 268 bundle2-output: start emission of HG20 stream
269 269 0 chunk
270 270 bundle2-output: bundle parameter:
271 271 1 chunk
272 272 bundle2-output: start of parts
273 273 bundle2-output: bundle part: "test:song"
274 274 bundle2-output-part: "test:song" (advisory) 178 bytes payload
275 275 bundle2-output: part 0: "test:song"
276 276 bundle2-output: header chunk size: 16
277 277 2 chunk
278 278 3 chunk
279 279 bundle2-output: payload chunk size: 178
280 280 4 chunk
281 281 5 chunk
282 282 bundle2-generatorexit
283 283 fake timeout complete.
284 284
285 285 Test unbundling
286 286
287 287 $ hg bundle2 | hg statbundle2
288 288 options count: 0
289 289 parts count: 0
290 290
291 291 Test old style bundle are detected and refused
292 292
293 293 $ hg bundle --all --type v1 ../bundle.hg
294 294 1 changesets found
295 295 $ hg statbundle2 < ../bundle.hg
296 296 abort: unknown bundle version 10
297 297 [255]
298 298
299 299 Test parameters
300 300 =================
301 301
302 302 - some options
303 303 - no parts
304 304
305 305 advisory parameters, no value
306 306 -------------------------------
307 307
308 308 Simplest possible parameters form
309 309
310 310 Test generation simple option
311 311
312 312 $ hg bundle2 --param 'caution' | f --hexdump
313 313
314 314 0000: 48 47 32 30 00 00 00 07 63 61 75 74 69 6f 6e 00 |HG20....caution.|
315 315 0010: 00 00 00 |...|
316 316
317 317 Test unbundling
318 318
319 319 $ hg bundle2 --param 'caution' | hg statbundle2
320 320 options count: 1
321 321 - caution
322 322 parts count: 0
323 323
324 324 Test generation multiple option
325 325
326 326 $ hg bundle2 --param 'caution' --param 'meal' | f --hexdump
327 327
328 328 0000: 48 47 32 30 00 00 00 0c 63 61 75 74 69 6f 6e 20 |HG20....caution |
329 329 0010: 6d 65 61 6c 00 00 00 00 |meal....|
330 330
331 331 Test unbundling
332 332
333 333 $ hg bundle2 --param 'caution' --param 'meal' | hg statbundle2
334 334 options count: 2
335 335 - caution
336 336 - meal
337 337 parts count: 0
338 338
339 339 advisory parameters, with value
340 340 -------------------------------
341 341
342 342 Test generation
343 343
344 344 $ hg bundle2 --param 'caution' --param 'meal=vegan' --param 'elephants' | f --hexdump
345 345
346 346 0000: 48 47 32 30 00 00 00 1c 63 61 75 74 69 6f 6e 20 |HG20....caution |
347 347 0010: 6d 65 61 6c 3d 76 65 67 61 6e 20 65 6c 65 70 68 |meal=vegan eleph|
348 348 0020: 61 6e 74 73 00 00 00 00 |ants....|
349 349
350 350 Test unbundling
351 351
352 352 $ hg bundle2 --param 'caution' --param 'meal=vegan' --param 'elephants' | hg statbundle2
353 353 options count: 3
354 354 - caution
355 355 - elephants
356 356 - meal
357 357 vegan
358 358 parts count: 0
359 359
360 360 parameter with special char in value
361 361 ---------------------------------------------------
362 362
363 363 Test generation
364 364
365 365 $ hg bundle2 --param 'e|! 7/=babar%#==tutu' --param simple | f --hexdump
366 366
367 367 0000: 48 47 32 30 00 00 00 29 65 25 37 43 25 32 31 25 |HG20...)e%7C%21%|
368 368 0010: 32 30 37 2f 3d 62 61 62 61 72 25 32 35 25 32 33 |207/=babar%25%23|
369 369 0020: 25 33 44 25 33 44 74 75 74 75 20 73 69 6d 70 6c |%3D%3Dtutu simpl|
370 370 0030: 65 00 00 00 00 |e....|
371 371
372 372 Test unbundling
373 373
374 374 $ hg bundle2 --param 'e|! 7/=babar%#==tutu' --param simple | hg statbundle2
375 375 options count: 2
376 376 - e|! 7/
377 377 babar%#==tutu
378 378 - simple
379 379 parts count: 0
380 380
381 381 Test unknown mandatory option
382 382 ---------------------------------------------------
383 383
384 384 $ hg bundle2 --param 'Gravity' | hg statbundle2
385 385 abort: unknown parameters: Stream Parameter - Gravity
386 386 [255]
387 387
388 388 Test debug output
389 389 ---------------------------------------------------
390 390
391 391 bundling debug
392 392
393 393 $ hg bundle2 --debug --param 'e|! 7/=babar%#==tutu' --param simple ../out.hg2 --config progress.debug=true --config devel.bundle2.debug=true
394 394 bundle2-output-bundle: "HG20", (2 params) 0 parts total
395 395 bundle2-output: start emission of HG20 stream
396 396 bundle2-output: bundle parameter: e%7C%21%207/=babar%25%23%3D%3Dtutu simple
397 397 bundle2-output: start of parts
398 398 bundle2-output: end of bundle
399 399
400 400 file content is ok
401 401
402 402 $ f --hexdump ../out.hg2
403 403 ../out.hg2:
404 404 0000: 48 47 32 30 00 00 00 29 65 25 37 43 25 32 31 25 |HG20...)e%7C%21%|
405 405 0010: 32 30 37 2f 3d 62 61 62 61 72 25 32 35 25 32 33 |207/=babar%25%23|
406 406 0020: 25 33 44 25 33 44 74 75 74 75 20 73 69 6d 70 6c |%3D%3Dtutu simpl|
407 407 0030: 65 00 00 00 00 |e....|
408 408
409 409 unbundling debug
410 410
411 411 $ hg statbundle2 --debug --config progress.debug=true --config devel.bundle2.debug=true < ../out.hg2
412 412 bundle2-input: start processing of HG20 stream
413 413 bundle2-input: reading bundle2 stream parameters
414 414 bundle2-input: ignoring unknown parameter e|! 7/
415 415 bundle2-input: ignoring unknown parameter simple
416 416 options count: 2
417 417 - e|! 7/
418 418 babar%#==tutu
419 419 - simple
420 420 bundle2-input: start extraction of bundle2 parts
421 421 bundle2-input: part header size: 0
422 422 bundle2-input: end of bundle2 stream
423 423 parts count: 0
424 424
425 425
426 426 Test buggy input
427 427 ---------------------------------------------------
428 428
429 429 empty parameter name
430 430
431 431 $ hg bundle2 --param '' --quiet
432 432 abort: empty parameter name
433 433 [255]
434 434
435 435 bad parameter name
436 436
437 437 $ hg bundle2 --param 42babar
438 438 abort: non letter first character: 42babar
439 439 [255]
440 440
441 441
442 442 Test part
443 443 =================
444 444
445 445 $ hg bundle2 --parts ../parts.hg2 --debug --config progress.debug=true --config devel.bundle2.debug=true
446 446 bundle2-output-bundle: "HG20", 7 parts total
447 447 bundle2-output: start emission of HG20 stream
448 448 bundle2-output: bundle parameter:
449 449 bundle2-output: start of parts
450 450 bundle2-output: bundle part: "test:empty"
451 451 bundle2-output-part: "test:empty" (advisory) empty payload
452 452 bundle2-output: part 0: "test:empty"
453 453 bundle2-output: header chunk size: 17
454 454 bundle2-output: closing payload chunk
455 455 bundle2-output: bundle part: "test:empty"
456 456 bundle2-output-part: "test:empty" (advisory) empty payload
457 457 bundle2-output: part 1: "test:empty"
458 458 bundle2-output: header chunk size: 17
459 459 bundle2-output: closing payload chunk
460 460 bundle2-output: bundle part: "test:song"
461 461 bundle2-output-part: "test:song" (advisory) 178 bytes payload
462 462 bundle2-output: part 2: "test:song"
463 463 bundle2-output: header chunk size: 16
464 464 bundle2-output: payload chunk size: 178
465 465 bundle2-output: closing payload chunk
466 466 bundle2-output: bundle part: "test:debugreply"
467 467 bundle2-output-part: "test:debugreply" (advisory) empty payload
468 468 bundle2-output: part 3: "test:debugreply"
469 469 bundle2-output: header chunk size: 22
470 470 bundle2-output: closing payload chunk
471 471 bundle2-output: bundle part: "test:math"
472 472 bundle2-output-part: "test:math" (advisory) (params: 2 mandatory 2 advisory) 2 bytes payload
473 473 bundle2-output: part 4: "test:math"
474 474 bundle2-output: header chunk size: 43
475 475 bundle2-output: payload chunk size: 2
476 476 bundle2-output: closing payload chunk
477 477 bundle2-output: bundle part: "test:song"
478 478 bundle2-output-part: "test:song" (advisory) (params: 1 mandatory) empty payload
479 479 bundle2-output: part 5: "test:song"
480 480 bundle2-output: header chunk size: 29
481 481 bundle2-output: closing payload chunk
482 482 bundle2-output: bundle part: "test:ping"
483 483 bundle2-output-part: "test:ping" (advisory) empty payload
484 484 bundle2-output: part 6: "test:ping"
485 485 bundle2-output: header chunk size: 16
486 486 bundle2-output: closing payload chunk
487 487 bundle2-output: end of bundle
488 488
489 489 $ f --hexdump ../parts.hg2
490 490 ../parts.hg2:
491 491 0000: 48 47 32 30 00 00 00 00 00 00 00 11 0a 74 65 73 |HG20.........tes|
492 492 0010: 74 3a 65 6d 70 74 79 00 00 00 00 00 00 00 00 00 |t:empty.........|
493 493 0020: 00 00 00 00 11 0a 74 65 73 74 3a 65 6d 70 74 79 |......test:empty|
494 494 0030: 00 00 00 01 00 00 00 00 00 00 00 00 00 10 09 74 |...............t|
495 495 0040: 65 73 74 3a 73 6f 6e 67 00 00 00 02 00 00 00 00 |est:song........|
496 496 0050: 00 b2 50 61 74 61 6c 69 20 44 69 72 61 70 61 74 |..Patali Dirapat|
497 497 0060: 61 2c 20 43 72 6f 6d 64 61 20 43 72 6f 6d 64 61 |a, Cromda Cromda|
498 498 0070: 20 52 69 70 61 6c 6f 2c 20 50 61 74 61 20 50 61 | Ripalo, Pata Pa|
499 499 0080: 74 61 2c 20 4b 6f 20 4b 6f 20 4b 6f 0a 42 6f 6b |ta, Ko Ko Ko.Bok|
500 500 0090: 6f 72 6f 20 44 69 70 6f 75 6c 69 74 6f 2c 20 52 |oro Dipoulito, R|
501 501 00a0: 6f 6e 64 69 20 52 6f 6e 64 69 20 50 65 70 69 6e |ondi Rondi Pepin|
502 502 00b0: 6f 2c 20 50 61 74 61 20 50 61 74 61 2c 20 4b 6f |o, Pata Pata, Ko|
503 503 00c0: 20 4b 6f 20 4b 6f 0a 45 6d 61 6e 61 20 4b 61 72 | Ko Ko.Emana Kar|
504 504 00d0: 61 73 73 6f 6c 69 2c 20 4c 6f 75 63 72 61 20 4c |assoli, Loucra L|
505 505 00e0: 6f 75 63 72 61 20 50 6f 6e 70 6f 6e 74 6f 2c 20 |oucra Ponponto, |
506 506 00f0: 50 61 74 61 20 50 61 74 61 2c 20 4b 6f 20 4b 6f |Pata Pata, Ko Ko|
507 507 0100: 20 4b 6f 2e 00 00 00 00 00 00 00 16 0f 74 65 73 | Ko..........tes|
508 508 0110: 74 3a 64 65 62 75 67 72 65 70 6c 79 00 00 00 03 |t:debugreply....|
509 509 0120: 00 00 00 00 00 00 00 00 00 2b 09 74 65 73 74 3a |.........+.test:|
510 510 0130: 6d 61 74 68 00 00 00 04 02 01 02 04 01 04 07 03 |math............|
511 511 0140: 70 69 33 2e 31 34 65 32 2e 37 32 63 6f 6f 6b 69 |pi3.14e2.72cooki|
512 512 0150: 6e 67 72 61 77 00 00 00 02 34 32 00 00 00 00 00 |ngraw....42.....|
513 513 0160: 00 00 1d 09 74 65 73 74 3a 73 6f 6e 67 00 00 00 |....test:song...|
514 514 0170: 05 01 00 0b 00 72 61 6e 64 6f 6d 70 61 72 61 6d |.....randomparam|
515 515 0180: 00 00 00 00 00 00 00 10 09 74 65 73 74 3a 70 69 |.........test:pi|
516 516 0190: 6e 67 00 00 00 06 00 00 00 00 00 00 00 00 00 00 |ng..............|
517 517
518 518
519 519 $ hg statbundle2 < ../parts.hg2
520 520 options count: 0
521 521 :test:empty:
522 522 mandatory: 0
523 523 advisory: 0
524 524 payload: 0 bytes
525 525 :test:empty:
526 526 mandatory: 0
527 527 advisory: 0
528 528 payload: 0 bytes
529 529 :test:song:
530 530 mandatory: 0
531 531 advisory: 0
532 532 payload: 178 bytes
533 533 :test:debugreply:
534 534 mandatory: 0
535 535 advisory: 0
536 536 payload: 0 bytes
537 537 :test:math:
538 538 mandatory: 2
539 539 advisory: 1
540 540 payload: 2 bytes
541 541 :test:song:
542 542 mandatory: 1
543 543 advisory: 0
544 544 payload: 0 bytes
545 545 :test:ping:
546 546 mandatory: 0
547 547 advisory: 0
548 548 payload: 0 bytes
549 549 parts count: 7
550 550
551 551 $ hg statbundle2 --debug --config progress.debug=true --config devel.bundle2.debug=true < ../parts.hg2
552 552 bundle2-input: start processing of HG20 stream
553 553 bundle2-input: reading bundle2 stream parameters
554 554 options count: 0
555 555 bundle2-input: start extraction of bundle2 parts
556 556 bundle2-input: part header size: 17
557 557 bundle2-input: part type: "test:empty"
558 558 bundle2-input: part id: "0"
559 559 bundle2-input: part parameters: 0
560 560 :test:empty:
561 561 mandatory: 0
562 562 advisory: 0
563 563 bundle2-input: payload chunk size: 0
564 564 payload: 0 bytes
565 565 bundle2-input: part header size: 17
566 566 bundle2-input: part type: "test:empty"
567 567 bundle2-input: part id: "1"
568 568 bundle2-input: part parameters: 0
569 569 :test:empty:
570 570 mandatory: 0
571 571 advisory: 0
572 572 bundle2-input: payload chunk size: 0
573 573 payload: 0 bytes
574 574 bundle2-input: part header size: 16
575 575 bundle2-input: part type: "test:song"
576 576 bundle2-input: part id: "2"
577 577 bundle2-input: part parameters: 0
578 578 :test:song:
579 579 mandatory: 0
580 580 advisory: 0
581 581 bundle2-input: payload chunk size: 178
582 582 bundle2-input: payload chunk size: 0
583 583 bundle2-input-part: total payload size 178
584 584 payload: 178 bytes
585 585 bundle2-input: part header size: 22
586 586 bundle2-input: part type: "test:debugreply"
587 587 bundle2-input: part id: "3"
588 588 bundle2-input: part parameters: 0
589 589 :test:debugreply:
590 590 mandatory: 0
591 591 advisory: 0
592 592 bundle2-input: payload chunk size: 0
593 593 payload: 0 bytes
594 594 bundle2-input: part header size: 43
595 595 bundle2-input: part type: "test:math"
596 596 bundle2-input: part id: "4"
597 597 bundle2-input: part parameters: 3
598 598 :test:math:
599 599 mandatory: 2
600 600 advisory: 1
601 601 bundle2-input: payload chunk size: 2
602 602 bundle2-input: payload chunk size: 0
603 603 bundle2-input-part: total payload size 2
604 604 payload: 2 bytes
605 605 bundle2-input: part header size: 29
606 606 bundle2-input: part type: "test:song"
607 607 bundle2-input: part id: "5"
608 608 bundle2-input: part parameters: 1
609 609 :test:song:
610 610 mandatory: 1
611 611 advisory: 0
612 612 bundle2-input: payload chunk size: 0
613 613 payload: 0 bytes
614 614 bundle2-input: part header size: 16
615 615 bundle2-input: part type: "test:ping"
616 616 bundle2-input: part id: "6"
617 617 bundle2-input: part parameters: 0
618 618 :test:ping:
619 619 mandatory: 0
620 620 advisory: 0
621 621 bundle2-input: payload chunk size: 0
622 622 payload: 0 bytes
623 623 bundle2-input: part header size: 0
624 624 bundle2-input: end of bundle2 stream
625 625 parts count: 7
626 626
627 627 Test actual unbundling of test part
628 628 =======================================
629 629
630 630 Process the bundle
631 631
632 632 $ hg unbundle2 --debug --config progress.debug=true --config devel.bundle2.debug=true < ../parts.hg2
633 633 bundle2-input: start processing of HG20 stream
634 634 bundle2-input: reading bundle2 stream parameters
635 635 bundle2-input-bundle: with-transaction
636 636 bundle2-input: start extraction of bundle2 parts
637 637 bundle2-input: part header size: 17
638 638 bundle2-input: part type: "test:empty"
639 639 bundle2-input: part id: "0"
640 640 bundle2-input: part parameters: 0
641 641 bundle2-input: ignoring unsupported advisory part test:empty
642 642 bundle2-input-part: "test:empty" (advisory) unsupported-type
643 643 bundle2-input: payload chunk size: 0
644 644 bundle2-input: part header size: 17
645 645 bundle2-input: part type: "test:empty"
646 646 bundle2-input: part id: "1"
647 647 bundle2-input: part parameters: 0
648 648 bundle2-input: ignoring unsupported advisory part test:empty
649 649 bundle2-input-part: "test:empty" (advisory) unsupported-type
650 650 bundle2-input: payload chunk size: 0
651 651 bundle2-input: part header size: 16
652 652 bundle2-input: part type: "test:song"
653 653 bundle2-input: part id: "2"
654 654 bundle2-input: part parameters: 0
655 655 bundle2-input: found a handler for part test:song
656 656 bundle2-input-part: "test:song" (advisory) supported
657 657 The choir starts singing:
658 658 bundle2-input: payload chunk size: 178
659 659 bundle2-input: payload chunk size: 0
660 660 bundle2-input-part: total payload size 178
661 661 Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
662 662 Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
663 663 Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko.
664 664 bundle2-input: part header size: 22
665 665 bundle2-input: part type: "test:debugreply"
666 666 bundle2-input: part id: "3"
667 667 bundle2-input: part parameters: 0
668 668 bundle2-input: found a handler for part test:debugreply
669 669 bundle2-input-part: "test:debugreply" (advisory) supported
670 670 debugreply: no reply
671 671 bundle2-input: payload chunk size: 0
672 672 bundle2-input: part header size: 43
673 673 bundle2-input: part type: "test:math"
674 674 bundle2-input: part id: "4"
675 675 bundle2-input: part parameters: 3
676 676 bundle2-input: ignoring unsupported advisory part test:math
677 677 bundle2-input-part: "test:math" (advisory) (params: 2 mandatory 2 advisory) unsupported-type
678 678 bundle2-input: payload chunk size: 2
679 679 bundle2-input: payload chunk size: 0
680 680 bundle2-input-part: total payload size 2
681 681 bundle2-input: part header size: 29
682 682 bundle2-input: part type: "test:song"
683 683 bundle2-input: part id: "5"
684 684 bundle2-input: part parameters: 1
685 685 bundle2-input: found a handler for part test:song
686 686 bundle2-input: ignoring unsupported advisory part test:song - randomparam
687 687 bundle2-input-part: "test:song" (advisory) (params: 1 mandatory) unsupported-params (randomparam)
688 688 bundle2-input: payload chunk size: 0
689 689 bundle2-input: part header size: 16
690 690 bundle2-input: part type: "test:ping"
691 691 bundle2-input: part id: "6"
692 692 bundle2-input: part parameters: 0
693 693 bundle2-input: found a handler for part test:ping
694 694 bundle2-input-part: "test:ping" (advisory) supported
695 695 received ping request (id 6)
696 696 bundle2-input: payload chunk size: 0
697 697 bundle2-input: part header size: 0
698 698 bundle2-input: end of bundle2 stream
699 699 bundle2-input-bundle: 6 parts total
700 700 0 unread bytes
701 701 3 total verses sung
702 702
703 703 Unbundle with an unknown mandatory part
704 704 (should abort)
705 705
706 706 $ hg bundle2 --parts --unknown ../unknown.hg2
707 707
708 708 $ hg unbundle2 < ../unknown.hg2
709 709 The choir starts singing:
710 710 Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
711 711 Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
712 712 Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko.
713 713 debugreply: no reply
714 714 0 unread bytes
715 715 abort: missing support for test:unknown
716 716 [255]
717 717
718 718 Unbundle with an unknown mandatory part parameters
719 719 (should abort)
720 720
721 721 $ hg bundle2 --unknownparams ../unknown.hg2
722 722
723 723 $ hg unbundle2 < ../unknown.hg2
724 724 0 unread bytes
725 725 abort: missing support for test:song - randomparams
726 726 [255]
727 727
728 728 unbundle with a reply
729 729
730 730 $ hg bundle2 --parts --reply ../parts-reply.hg2
731 731 $ hg unbundle2 ../reply.hg2 < ../parts-reply.hg2
732 732 0 unread bytes
733 733 3 total verses sung
734 734
735 735 The reply is a bundle
736 736
737 737 $ f --hexdump ../reply.hg2
738 738 ../reply.hg2:
739 739 0000: 48 47 32 30 00 00 00 00 00 00 00 1b 06 6f 75 74 |HG20.........out|
740 740 0010: 70 75 74 00 00 00 00 00 01 0b 01 69 6e 2d 72 65 |put........in-re|
741 741 0020: 70 6c 79 2d 74 6f 33 00 00 00 d9 54 68 65 20 63 |ply-to3....The c|
742 742 0030: 68 6f 69 72 20 73 74 61 72 74 73 20 73 69 6e 67 |hoir starts sing|
743 743 0040: 69 6e 67 3a 0a 20 20 20 20 50 61 74 61 6c 69 20 |ing:. Patali |
744 744 0050: 44 69 72 61 70 61 74 61 2c 20 43 72 6f 6d 64 61 |Dirapata, Cromda|
745 745 0060: 20 43 72 6f 6d 64 61 20 52 69 70 61 6c 6f 2c 20 | Cromda Ripalo, |
746 746 0070: 50 61 74 61 20 50 61 74 61 2c 20 4b 6f 20 4b 6f |Pata Pata, Ko Ko|
747 747 0080: 20 4b 6f 0a 20 20 20 20 42 6f 6b 6f 72 6f 20 44 | Ko. Bokoro D|
748 748 0090: 69 70 6f 75 6c 69 74 6f 2c 20 52 6f 6e 64 69 20 |ipoulito, Rondi |
749 749 00a0: 52 6f 6e 64 69 20 50 65 70 69 6e 6f 2c 20 50 61 |Rondi Pepino, Pa|
750 750 00b0: 74 61 20 50 61 74 61 2c 20 4b 6f 20 4b 6f 20 4b |ta Pata, Ko Ko K|
751 751 00c0: 6f 0a 20 20 20 20 45 6d 61 6e 61 20 4b 61 72 61 |o. Emana Kara|
752 752 00d0: 73 73 6f 6c 69 2c 20 4c 6f 75 63 72 61 20 4c 6f |ssoli, Loucra Lo|
753 753 00e0: 75 63 72 61 20 50 6f 6e 70 6f 6e 74 6f 2c 20 50 |ucra Ponponto, P|
754 754 00f0: 61 74 61 20 50 61 74 61 2c 20 4b 6f 20 4b 6f 20 |ata Pata, Ko Ko |
755 755 0100: 4b 6f 2e 0a 00 00 00 00 00 00 00 1b 06 6f 75 74 |Ko...........out|
756 756 0110: 70 75 74 00 00 00 01 00 01 0b 01 69 6e 2d 72 65 |put........in-re|
757 757 0120: 70 6c 79 2d 74 6f 34 00 00 00 c9 64 65 62 75 67 |ply-to4....debug|
758 758 0130: 72 65 70 6c 79 3a 20 63 61 70 61 62 69 6c 69 74 |reply: capabilit|
759 759 0140: 69 65 73 3a 0a 64 65 62 75 67 72 65 70 6c 79 3a |ies:.debugreply:|
760 760 0150: 20 20 20 20 20 27 63 69 74 79 3d 21 27 0a 64 65 | 'city=!'.de|
761 761 0160: 62 75 67 72 65 70 6c 79 3a 20 20 20 20 20 20 20 |bugreply: |
762 762 0170: 20 20 27 63 65 6c 65 73 74 65 2c 76 69 6c 6c 65 | 'celeste,ville|
763 763 0180: 27 0a 64 65 62 75 67 72 65 70 6c 79 3a 20 20 20 |'.debugreply: |
764 764 0190: 20 20 27 65 6c 65 70 68 61 6e 74 73 27 0a 64 65 | 'elephants'.de|
765 765 01a0: 62 75 67 72 65 70 6c 79 3a 20 20 20 20 20 20 20 |bugreply: |
766 766 01b0: 20 20 27 62 61 62 61 72 27 0a 64 65 62 75 67 72 | 'babar'.debugr|
767 767 01c0: 65 70 6c 79 3a 20 20 20 20 20 20 20 20 20 27 63 |eply: 'c|
768 768 01d0: 65 6c 65 73 74 65 27 0a 64 65 62 75 67 72 65 70 |eleste'.debugrep|
769 769 01e0: 6c 79 3a 20 20 20 20 20 27 70 69 6e 67 2d 70 6f |ly: 'ping-po|
770 770 01f0: 6e 67 27 0a 00 00 00 00 00 00 00 1e 09 74 65 73 |ng'..........tes|
771 771 0200: 74 3a 70 6f 6e 67 00 00 00 02 01 00 0b 01 69 6e |t:pong........in|
772 772 0210: 2d 72 65 70 6c 79 2d 74 6f 37 00 00 00 00 00 00 |-reply-to7......|
773 773 0220: 00 1b 06 6f 75 74 70 75 74 00 00 00 03 00 01 0b |...output.......|
774 774 0230: 01 69 6e 2d 72 65 70 6c 79 2d 74 6f 37 00 00 00 |.in-reply-to7...|
775 775 0240: 3d 72 65 63 65 69 76 65 64 20 70 69 6e 67 20 72 |=received ping r|
776 776 0250: 65 71 75 65 73 74 20 28 69 64 20 37 29 0a 72 65 |equest (id 7).re|
777 777 0260: 70 6c 79 69 6e 67 20 74 6f 20 70 69 6e 67 20 72 |plying to ping r|
778 778 0270: 65 71 75 65 73 74 20 28 69 64 20 37 29 0a 00 00 |equest (id 7)...|
779 779 0280: 00 00 00 00 00 00 |......|
780 780
781 781 The reply is valid
782 782
783 783 $ hg statbundle2 < ../reply.hg2
784 784 options count: 0
785 785 :output:
786 786 mandatory: 0
787 787 advisory: 1
788 788 payload: 217 bytes
789 789 :output:
790 790 mandatory: 0
791 791 advisory: 1
792 792 payload: 201 bytes
793 793 :test:pong:
794 794 mandatory: 1
795 795 advisory: 0
796 796 payload: 0 bytes
797 797 :output:
798 798 mandatory: 0
799 799 advisory: 1
800 800 payload: 61 bytes
801 801 parts count: 4
802 802
803 803 Unbundle the reply to get the output:
804 804
805 805 $ hg unbundle2 < ../reply.hg2
806 806 remote: The choir starts singing:
807 807 remote: Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
808 808 remote: Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
809 809 remote: Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko.
810 810 remote: debugreply: capabilities:
811 811 remote: debugreply: 'city=!'
812 812 remote: debugreply: 'celeste,ville'
813 813 remote: debugreply: 'elephants'
814 814 remote: debugreply: 'babar'
815 815 remote: debugreply: 'celeste'
816 816 remote: debugreply: 'ping-pong'
817 817 remote: received ping request (id 7)
818 818 remote: replying to ping request (id 7)
819 819 0 unread bytes
820 820
821 821 Test push race detection
822 822
823 823 $ hg bundle2 --pushrace ../part-race.hg2
824 824
825 825 $ hg unbundle2 < ../part-race.hg2
826 826 0 unread bytes
827 827 abort: push race: repository changed while pushing - please try again
828 828 [255]
829 829
830 830 Support for changegroup
831 831 ===================================
832 832
833 833 $ hg unbundle $TESTDIR/bundles/rebase.hg
834 834 adding changesets
835 835 adding manifests
836 836 adding file changes
837 837 added 8 changesets with 7 changes to 7 files (+3 heads)
838 838 new changesets cd010b8cd998:02de42196ebe
839 839 (run 'hg heads' to see heads, 'hg merge' to merge)
840 840
841 841 $ hg log -G
842 842 o 8:02de42196ebe draft Nicolas Dumazet <nicdumz.commits@gmail.com> H
843 843 |
844 844 | o 7:eea13746799a draft Nicolas Dumazet <nicdumz.commits@gmail.com> G
845 845 |/|
846 846 o | 6:24b6387c8c8c draft Nicolas Dumazet <nicdumz.commits@gmail.com> F
847 847 | |
848 848 | o 5:9520eea781bc draft Nicolas Dumazet <nicdumz.commits@gmail.com> E
849 849 |/
850 850 | o 4:32af7686d403 draft Nicolas Dumazet <nicdumz.commits@gmail.com> D
851 851 | |
852 852 | o 3:5fddd98957c8 draft Nicolas Dumazet <nicdumz.commits@gmail.com> C
853 853 | |
854 854 | o 2:42ccdea3bb16 draft Nicolas Dumazet <nicdumz.commits@gmail.com> B
855 855 |/
856 856 o 1:cd010b8cd998 draft Nicolas Dumazet <nicdumz.commits@gmail.com> A
857 857
858 858 @ 0:3903775176ed draft test a
859 859
860 860
861 861 $ hg bundle2 --debug --config progress.debug=true --config devel.bundle2.debug=true --rev '8+7+5+4' ../rev.hg2
862 862 4 changesets found
863 863 list of changesets:
864 864 32af7686d403cf45b5d95f2d70cebea587ac806a
865 865 9520eea781bcca16c1e15acc0ba14335a0e8e5ba
866 866 eea13746799a9e0bfd88f29d3c2e9dc9389f524f
867 867 02de42196ebee42ef284b6780a87cdc96e8eaab6
868 868 bundle2-output-bundle: "HG20", 1 parts total
869 869 bundle2-output: start emission of HG20 stream
870 870 bundle2-output: bundle parameter:
871 871 bundle2-output: start of parts
872 872 bundle2-output: bundle part: "changegroup"
873 873 bundle2-output-part: "changegroup" (advisory) streamed payload
874 874 bundle2-output: part 0: "changegroup"
875 875 bundle2-output: header chunk size: 18
876 876 bundling: 1/4 changesets (25.00%)
877 877 bundling: 2/4 changesets (50.00%)
878 878 bundling: 3/4 changesets (75.00%)
879 879 bundling: 4/4 changesets (100.00%)
880 880 bundling: 1/4 manifests (25.00%)
881 881 bundling: 2/4 manifests (50.00%)
882 882 bundling: 3/4 manifests (75.00%)
883 883 bundling: 4/4 manifests (100.00%)
884 884 bundling: D 1/3 files (33.33%)
885 885 bundling: E 2/3 files (66.67%)
886 886 bundling: H 3/3 files (100.00%)
887 887 bundle2-output: payload chunk size: 1555
888 888 bundle2-output: closing payload chunk
889 889 bundle2-output: end of bundle
890 890
891 891 $ f --hexdump ../rev.hg2
892 892 ../rev.hg2:
893 893 0000: 48 47 32 30 00 00 00 00 00 00 00 12 0b 63 68 61 |HG20.........cha|
894 894 0010: 6e 67 65 67 72 6f 75 70 00 00 00 00 00 00 00 00 |ngegroup........|
895 895 0020: 06 13 00 00 00 a4 32 af 76 86 d4 03 cf 45 b5 d9 |......2.v....E..|
896 896 0030: 5f 2d 70 ce be a5 87 ac 80 6a 5f dd d9 89 57 c8 |_-p......j_...W.|
897 897 0040: a5 4a 4d 43 6d fe 1d a9 d8 7f 21 a1 b9 7b 00 00 |.JMCm.....!..{..|
898 898 0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
899 899 0060: 00 00 32 af 76 86 d4 03 cf 45 b5 d9 5f 2d 70 ce |..2.v....E.._-p.|
900 900 0070: be a5 87 ac 80 6a 00 00 00 00 00 00 00 29 00 00 |.....j.......)..|
901 901 0080: 00 29 36 65 31 66 34 63 34 37 65 63 62 35 33 33 |.)6e1f4c47ecb533|
902 902 0090: 66 66 64 30 63 38 65 35 32 63 64 63 38 38 61 66 |ffd0c8e52cdc88af|
903 903 00a0: 62 36 63 64 33 39 65 32 30 63 0a 00 00 00 66 00 |b6cd39e20c....f.|
904 904 00b0: 00 00 68 00 00 00 02 44 0a 00 00 00 69 00 00 00 |..h....D....i...|
905 905 00c0: 6a 00 00 00 01 44 00 00 00 a4 95 20 ee a7 81 bc |j....D..... ....|
906 906 00d0: ca 16 c1 e1 5a cc 0b a1 43 35 a0 e8 e5 ba cd 01 |....Z...C5......|
907 907 00e0: 0b 8c d9 98 f3 98 1a 5a 81 15 f9 4f 8d a4 ab 50 |.......Z...O...P|
908 908 00f0: 60 89 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |`...............|
909 909 0100: 00 00 00 00 00 00 95 20 ee a7 81 bc ca 16 c1 e1 |....... ........|
910 910 0110: 5a cc 0b a1 43 35 a0 e8 e5 ba 00 00 00 00 00 00 |Z...C5..........|
911 911 0120: 00 29 00 00 00 29 34 64 65 63 65 39 63 38 32 36 |.)...)4dece9c826|
912 912 0130: 66 36 39 34 39 30 35 30 37 62 39 38 63 36 33 38 |f69490507b98c638|
913 913 0140: 33 61 33 30 30 39 62 32 39 35 38 33 37 64 0a 00 |3a3009b295837d..|
914 914 0150: 00 00 66 00 00 00 68 00 00 00 02 45 0a 00 00 00 |..f...h....E....|
915 915 0160: 69 00 00 00 6a 00 00 00 01 45 00 00 00 a2 ee a1 |i...j....E......|
916 916 0170: 37 46 79 9a 9e 0b fd 88 f2 9d 3c 2e 9d c9 38 9f |7Fy.......<...8.|
917 917 0180: 52 4f 24 b6 38 7c 8c 8c ae 37 17 88 80 f3 fa 95 |RO$.8|...7......|
918 918 0190: de d3 cb 1c f7 85 95 20 ee a7 81 bc ca 16 c1 e1 |....... ........|
919 919 01a0: 5a cc 0b a1 43 35 a0 e8 e5 ba ee a1 37 46 79 9a |Z...C5......7Fy.|
920 920 01b0: 9e 0b fd 88 f2 9d 3c 2e 9d c9 38 9f 52 4f 00 00 |......<...8.RO..|
921 921 01c0: 00 00 00 00 00 29 00 00 00 29 33 36 35 62 39 33 |.....)...)365b93|
922 922 01d0: 64 35 37 66 64 66 34 38 31 34 65 32 62 35 39 31 |d57fdf4814e2b591|
923 923 01e0: 31 64 36 62 61 63 66 66 32 62 31 32 30 31 34 34 |1d6bacff2b120144|
924 924 01f0: 34 31 0a 00 00 00 66 00 00 00 68 00 00 00 00 00 |41....f...h.....|
925 925 0200: 00 00 69 00 00 00 6a 00 00 00 01 47 00 00 00 a4 |..i...j....G....|
926 926 0210: 02 de 42 19 6e be e4 2e f2 84 b6 78 0a 87 cd c9 |..B.n......x....|
927 927 0220: 6e 8e aa b6 24 b6 38 7c 8c 8c ae 37 17 88 80 f3 |n...$.8|...7....|
928 928 0230: fa 95 de d3 cb 1c f7 85 00 00 00 00 00 00 00 00 |................|
929 929 0240: 00 00 00 00 00 00 00 00 00 00 00 00 02 de 42 19 |..............B.|
930 930 0250: 6e be e4 2e f2 84 b6 78 0a 87 cd c9 6e 8e aa b6 |n......x....n...|
931 931 0260: 00 00 00 00 00 00 00 29 00 00 00 29 38 62 65 65 |.......)...)8bee|
932 932 0270: 34 38 65 64 63 37 33 31 38 35 34 31 66 63 30 30 |48edc7318541fc00|
933 933 0280: 31 33 65 65 34 31 62 30 38 39 32 37 36 61 38 63 |13ee41b089276a8c|
934 934 0290: 32 34 62 66 0a 00 00 00 66 00 00 00 66 00 00 00 |24bf....f...f...|
935 935 02a0: 02 48 0a 00 00 00 67 00 00 00 68 00 00 00 01 48 |.H....g...h....H|
936 936 02b0: 00 00 00 00 00 00 00 8b 6e 1f 4c 47 ec b5 33 ff |........n.LG..3.|
937 937 02c0: d0 c8 e5 2c dc 88 af b6 cd 39 e2 0c 66 a5 a0 18 |...,.....9..f...|
938 938 02d0: 17 fd f5 23 9c 27 38 02 b5 b7 61 8d 05 1c 89 e4 |...#.'8...a.....|
939 939 02e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
940 940 02f0: 00 00 00 00 32 af 76 86 d4 03 cf 45 b5 d9 5f 2d |....2.v....E.._-|
941 941 0300: 70 ce be a5 87 ac 80 6a 00 00 00 81 00 00 00 81 |p......j........|
942 942 0310: 00 00 00 2b 44 00 63 33 66 31 63 61 32 39 32 34 |...+D.c3f1ca2924|
943 943 0320: 63 31 36 61 31 39 62 30 36 35 36 61 38 34 39 30 |c16a19b0656a8490|
944 944 0330: 30 65 35 30 34 65 35 62 30 61 65 63 32 64 0a 00 |0e504e5b0aec2d..|
945 945 0340: 00 00 8b 4d ec e9 c8 26 f6 94 90 50 7b 98 c6 38 |...M...&...P{..8|
946 946 0350: 3a 30 09 b2 95 83 7d 00 7d 8c 9d 88 84 13 25 f5 |:0....}.}.....%.|
947 947 0360: c6 b0 63 71 b3 5b 4e 8a 2b 1a 83 00 00 00 00 00 |..cq.[N.+.......|
948 948 0370: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 95 |................|
949 949 0380: 20 ee a7 81 bc ca 16 c1 e1 5a cc 0b a1 43 35 a0 | ........Z...C5.|
950 950 0390: e8 e5 ba 00 00 00 2b 00 00 00 ac 00 00 00 2b 45 |......+.......+E|
951 951 03a0: 00 39 63 36 66 64 30 33 35 30 61 36 63 30 64 30 |.9c6fd0350a6c0d0|
952 952 03b0: 63 34 39 64 34 61 39 63 35 30 31 37 63 66 30 37 |c49d4a9c5017cf07|
953 953 03c0: 30 34 33 66 35 34 65 35 38 0a 00 00 00 8b 36 5b |043f54e58.....6[|
954 954 03d0: 93 d5 7f df 48 14 e2 b5 91 1d 6b ac ff 2b 12 01 |....H.....k..+..|
955 955 03e0: 44 41 28 a5 84 c6 5e f1 21 f8 9e b6 6a b7 d0 bc |DA(...^.!...j...|
956 956 03f0: 15 3d 80 99 e7 ce 4d ec e9 c8 26 f6 94 90 50 7b |.=....M...&...P{|
957 957 0400: 98 c6 38 3a 30 09 b2 95 83 7d ee a1 37 46 79 9a |..8:0....}..7Fy.|
958 958 0410: 9e 0b fd 88 f2 9d 3c 2e 9d c9 38 9f 52 4f 00 00 |......<...8.RO..|
959 959 0420: 00 56 00 00 00 56 00 00 00 2b 46 00 32 32 62 66 |.V...V...+F.22bf|
960 960 0430: 63 66 64 36 32 61 32 31 61 33 32 38 37 65 64 62 |cfd62a21a3287edb|
961 961 0440: 64 34 64 36 35 36 32 31 38 64 30 66 35 32 35 65 |d4d656218d0f525e|
962 962 0450: 64 37 36 61 0a 00 00 00 97 8b ee 48 ed c7 31 85 |d76a.......H..1.|
963 963 0460: 41 fc 00 13 ee 41 b0 89 27 6a 8c 24 bf 28 a5 84 |A....A..'j.$.(..|
964 964 0470: c6 5e f1 21 f8 9e b6 6a b7 d0 bc 15 3d 80 99 e7 |.^.!...j....=...|
965 965 0480: ce 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
966 966 0490: 00 00 00 00 00 02 de 42 19 6e be e4 2e f2 84 b6 |.......B.n......|
967 967 04a0: 78 0a 87 cd c9 6e 8e aa b6 00 00 00 2b 00 00 00 |x....n......+...|
968 968 04b0: 56 00 00 00 00 00 00 00 81 00 00 00 81 00 00 00 |V...............|
969 969 04c0: 2b 48 00 38 35 30 30 31 38 39 65 37 34 61 39 65 |+H.8500189e74a9e|
970 970 04d0: 30 34 37 35 65 38 32 32 30 39 33 62 63 37 64 62 |0475e822093bc7db|
971 971 04e0: 30 64 36 33 31 61 65 62 30 62 34 0a 00 00 00 00 |0d631aeb0b4.....|
972 972 04f0: 00 00 00 05 44 00 00 00 62 c3 f1 ca 29 24 c1 6a |....D...b...)$.j|
973 973 0500: 19 b0 65 6a 84 90 0e 50 4e 5b 0a ec 2d 00 00 00 |..ej...PN[..-...|
974 974 0510: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
975 975 0520: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
976 976 0530: 00 00 00 00 00 32 af 76 86 d4 03 cf 45 b5 d9 5f |.....2.v....E.._|
977 977 0540: 2d 70 ce be a5 87 ac 80 6a 00 00 00 00 00 00 00 |-p......j.......|
978 978 0550: 00 00 00 00 02 44 0a 00 00 00 00 00 00 00 05 45 |.....D.........E|
979 979 0560: 00 00 00 62 9c 6f d0 35 0a 6c 0d 0c 49 d4 a9 c5 |...b.o.5.l..I...|
980 980 0570: 01 7c f0 70 43 f5 4e 58 00 00 00 00 00 00 00 00 |.|.pC.NX........|
981 981 0580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
982 982 0590: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
983 983 05a0: 95 20 ee a7 81 bc ca 16 c1 e1 5a cc 0b a1 43 35 |. ........Z...C5|
984 984 05b0: a0 e8 e5 ba 00 00 00 00 00 00 00 00 00 00 00 02 |................|
985 985 05c0: 45 0a 00 00 00 00 00 00 00 05 48 00 00 00 62 85 |E.........H...b.|
986 986 05d0: 00 18 9e 74 a9 e0 47 5e 82 20 93 bc 7d b0 d6 31 |...t..G^. ..}..1|
987 987 05e0: ae b0 b4 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
988 988 05f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
989 989 0600: 00 00 00 00 00 00 00 00 00 00 00 02 de 42 19 6e |.............B.n|
990 990 0610: be e4 2e f2 84 b6 78 0a 87 cd c9 6e 8e aa b6 00 |......x....n....|
991 991 0620: 00 00 00 00 00 00 00 00 00 00 02 48 0a 00 00 00 |...........H....|
992 992 0630: 00 00 00 00 00 00 00 00 00 00 00 00 00 |.............|
993 993
994 994 $ hg debugbundle ../rev.hg2
995 995 Stream params: {}
996 changegroup -- {}
996 changegroup -- {} (mandatory: False)
997 997 32af7686d403cf45b5d95f2d70cebea587ac806a
998 998 9520eea781bcca16c1e15acc0ba14335a0e8e5ba
999 999 eea13746799a9e0bfd88f29d3c2e9dc9389f524f
1000 1000 02de42196ebee42ef284b6780a87cdc96e8eaab6
1001 1001 $ hg unbundle ../rev.hg2
1002 1002 adding changesets
1003 1003 adding manifests
1004 1004 adding file changes
1005 1005 added 0 changesets with 0 changes to 3 files
1006 1006 (run 'hg update' to get a working copy)
1007 1007
1008 1008 with reply
1009 1009
1010 1010 $ hg bundle2 --rev '8+7+5+4' --reply ../rev-rr.hg2
1011 1011 $ hg unbundle2 ../rev-reply.hg2 < ../rev-rr.hg2
1012 1012 0 unread bytes
1013 1013 addchangegroup return: 1
1014 1014
1015 1015 $ f --hexdump ../rev-reply.hg2
1016 1016 ../rev-reply.hg2:
1017 1017 0000: 48 47 32 30 00 00 00 00 00 00 00 2f 11 72 65 70 |HG20......./.rep|
1018 1018 0010: 6c 79 3a 63 68 61 6e 67 65 67 72 6f 75 70 00 00 |ly:changegroup..|
1019 1019 0020: 00 00 00 02 0b 01 06 01 69 6e 2d 72 65 70 6c 79 |........in-reply|
1020 1020 0030: 2d 74 6f 31 72 65 74 75 72 6e 31 00 00 00 00 00 |-to1return1.....|
1021 1021 0040: 00 00 1b 06 6f 75 74 70 75 74 00 00 00 01 00 01 |....output......|
1022 1022 0050: 0b 01 69 6e 2d 72 65 70 6c 79 2d 74 6f 31 00 00 |..in-reply-to1..|
1023 1023 0060: 00 64 61 64 64 69 6e 67 20 63 68 61 6e 67 65 73 |.dadding changes|
1024 1024 0070: 65 74 73 0a 61 64 64 69 6e 67 20 6d 61 6e 69 66 |ets.adding manif|
1025 1025 0080: 65 73 74 73 0a 61 64 64 69 6e 67 20 66 69 6c 65 |ests.adding file|
1026 1026 0090: 20 63 68 61 6e 67 65 73 0a 61 64 64 65 64 20 30 | changes.added 0|
1027 1027 00a0: 20 63 68 61 6e 67 65 73 65 74 73 20 77 69 74 68 | changesets with|
1028 1028 00b0: 20 30 20 63 68 61 6e 67 65 73 20 74 6f 20 33 20 | 0 changes to 3 |
1029 1029 00c0: 66 69 6c 65 73 0a 00 00 00 00 00 00 00 00 |files.........|
1030 1030
1031 1031 Check handling of exception during generation.
1032 1032 ----------------------------------------------
1033 1033
1034 1034 $ hg bundle2 --genraise > ../genfailed.hg2
1035 1035 abort: Someone set up us the bomb!
1036 1036 [255]
1037 1037
1038 1038 Should still be a valid bundle
1039 1039
1040 1040 $ f --hexdump ../genfailed.hg2
1041 1041 ../genfailed.hg2:
1042 1042 0000: 48 47 32 30 00 00 00 00 00 00 00 0d 06 6f 75 74 |HG20.........out|
1043 1043 0010: 70 75 74 00 00 00 00 00 00 ff ff ff ff 00 00 00 |put.............|
1044 1044 0020: 48 0b 65 72 72 6f 72 3a 61 62 6f 72 74 00 00 00 |H.error:abort...|
1045 1045 0030: 00 01 00 07 2d 6d 65 73 73 61 67 65 75 6e 65 78 |....-messageunex|
1046 1046 0040: 70 65 63 74 65 64 20 65 72 72 6f 72 3a 20 53 6f |pected error: So|
1047 1047 0050: 6d 65 6f 6e 65 20 73 65 74 20 75 70 20 75 73 20 |meone set up us |
1048 1048 0060: 74 68 65 20 62 6f 6d 62 21 00 00 00 00 00 00 00 |the bomb!.......|
1049 1049 0070: 00 |.|
1050 1050
1051 1051 And its handling on the other size raise a clean exception
1052 1052
1053 1053 $ cat ../genfailed.hg2 | hg unbundle2
1054 1054 0 unread bytes
1055 1055 abort: unexpected error: Someone set up us the bomb!
1056 1056 [255]
1057 1057
1058 1058 Test compression
1059 1059 ================
1060 1060
1061 1061 Simple case where it just work: GZ
1062 1062 ----------------------------------
1063 1063
1064 1064 $ hg bundle2 --compress GZ --rev '8+7+5+4' ../rev.hg2.bz
1065 1065 $ f --hexdump ../rev.hg2.bz
1066 1066 ../rev.hg2.bz:
1067 1067 0000: 48 47 32 30 00 00 00 0e 43 6f 6d 70 72 65 73 73 |HG20....Compress|
1068 1068 0010: 69 6f 6e 3d 47 5a 78 9c 95 94 7d 68 95 55 1c c7 |ion=GZx...}h.U..|
1069 1069 0020: 9f 3b 31 e8 ce fa c3 65 be a0 a4 b4 52 b9 29 e7 |.;1....e....R.).|
1070 1070 0030: f5 79 ce 89 fa 63 ed 5e 77 8b 9c c3 3f 2a 1c 68 |.y...c.^w...?*.h|
1071 1071 0040: cf 79 9b dd 6a ae b0 28 74 b8 e5 96 5b bb 86 61 |.y..j..(t...[..a|
1072 1072 0050: a3 15 6e 3a 71 c8 6a e8 a5 da 95 64 28 22 ce 69 |..n:q.j....d(".i|
1073 1073 0060: cd 06 59 34 28 2b 51 2a 58 c3 17 56 2a 9a 9d 67 |..Y4(+Q*X..V*..g|
1074 1074 0070: dc c6 35 9e c4 1d f8 9e 87 f3 9c f3 3b bf 0f bf |..5.........;...|
1075 1075 0080: 97 e3 38 ce f4 42 b9 d6 af ae d2 55 af ae 7b ad |..8..B.....U..{.|
1076 1076 0090: c6 c9 8d bb 8a ec b4 07 ed 7f fd ed d3 53 be 4e |.............S.N|
1077 1077 00a0: f4 0e af 59 52 73 ea 50 d7 96 9e ba d4 9a 1f 87 |...YRs.P........|
1078 1078 00b0: 9b 9f 1d e8 7a 6a 79 e9 cb 7f cf eb fe 7e d3 82 |....zjy......~..|
1079 1079 00c0: ce 2f 36 38 21 23 cc 36 b7 b5 38 90 ab a1 21 92 |./68!#.6..8...!.|
1080 1080 00d0: 78 5a 0a 8a b1 31 0a 48 a6 29 92 4a 32 e6 1b e1 |xZ...1.H.).J2...|
1081 1081 00e0: 4a 85 b9 46 40 46 ed 61 63 b5 d6 aa 20 1e ac 5e |J..F@F.ac... ..^|
1082 1082 00f0: b0 0a ae 8a c4 03 c6 d6 f9 a3 7b eb fb 4e de 7f |..........{..N..|
1083 1083 0100: e4 97 55 5f 15 76 96 d2 5d bf 9d 3f 38 18 29 4c |..U_.v..]..?8.)L|
1084 1084 0110: 0f b7 5d 6e 9b b3 aa 7e c6 d5 15 5b f7 7c 52 f1 |..]n...~...[.|R.|
1085 1085 0120: 7c 73 18 63 98 6d 3e 23 51 5a 6a 2e 19 72 8d cb ||s.c.m>#QZj..r..|
1086 1086 0130: 09 07 14 78 82 33 e9 62 86 7d 0c 00 17 88 53 86 |...x.3.b.}....S.|
1087 1087 0140: 3d 75 0b 63 e2 16 c6 84 9d 76 8f 76 7a cb de fc |=u.c.....v.vz...|
1088 1088 0150: a8 a3 f0 46 d3 a5 f6 c7 96 b6 9f 60 3b 57 ae 28 |...F.......`;W.(|
1089 1089 0160: ce b2 8d e9 f4 3e 6f 66 53 dd e5 6b ad 67 be f9 |.....>ofS..k.g..|
1090 1090 0170: 72 ee 5f 8d 61 3c 61 b6 f9 8c d8 a5 82 63 45 3d |r._.a<a......cE=|
1091 1091 0180: a3 0c 61 90 68 24 28 87 50 b9 c2 97 c6 20 01 11 |..a.h$(.P.... ..|
1092 1092 0190: 80 84 10 98 cf e8 e4 13 96 05 51 2c 38 f3 c4 ec |..........Q,8...|
1093 1093 01a0: ea 43 e7 96 5e 6a c8 be 11 dd 32 78 a2 fa dd 8f |.C..^j....2x....|
1094 1094 01b0: b3 61 84 61 51 0c b3 cd 27 64 42 6b c2 b4 92 1e |.a.aQ...'dBk....|
1095 1095 01c0: 86 8c 12 68 24 00 10 db 7f 50 00 c6 91 e7 fa 4c |...h$....P.....L|
1096 1096 01d0: 22 22 cc bf 84 81 0a 92 c1 aa 2a c7 1b 49 e6 ee |""........*..I..|
1097 1097 01e0: 6b a9 7e e0 e9 b2 91 5e 7c 73 68 e0 fc 23 3f 34 |k.~....^|sh..#?4|
1098 1098 01f0: ed cf 0e f2 b3 d3 4c d7 ae 59 33 6f 8c 3d b8 63 |......L..Y3o.=.c|
1099 1099 0200: 21 2b e8 3d e0 6f 9d 3a b7 f9 dc 24 2a b2 3e a7 |!+.=.o.:...$*.>.|
1100 1100 0210: 58 dc 91 d8 40 e9 23 8e 88 84 ae 0f b9 00 2e b5 |X...@.#.........|
1101 1101 0220: 74 36 f3 40 53 40 34 15 c0 d7 12 8d e7 bb 65 f9 |t6.@S@4.......e.|
1102 1102 0230: c8 ef 03 0f ff f9 fe b6 8a 0d 6d fd ec 51 70 f7 |..........m..Qp.|
1103 1103 0240: a7 ad 9b 6b 9d da 74 7b 53 43 d1 43 63 fd 19 f9 |...k..t{SC.Cc...|
1104 1104 0250: ca 67 95 e5 ef c4 e6 6c 9e 44 e1 c5 ac 7a 82 6f |.g.....l.D...z.o|
1105 1105 0260: c2 e1 d2 b5 2d 81 29 f0 5d 09 6c 6f 10 ae 88 cf |....-.).].lo....|
1106 1106 0270: 25 05 d0 93 06 78 80 60 43 2d 10 1b 47 71 2b b7 |%....x.`C-..Gq+.|
1107 1107 0280: 7f bb e9 a7 e4 7d 67 7b df 9b f7 62 cf cd d8 f4 |.....}g{...b....|
1108 1108 0290: 48 bc 64 51 57 43 ff ea 8b 0b ae 74 64 53 07 86 |H.dQWC.....tdS..|
1109 1109 02a0: fa 66 3c 5e f7 e1 af a7 c2 90 ff a7 be 9e c9 29 |.f<^...........)|
1110 1110 02b0: b6 cc 41 48 18 69 94 8b 7c 04 7d 8c 98 a7 95 50 |..AH.i..|.}....P|
1111 1111 02c0: 44 d9 d0 20 c8 14 30 14 51 ad 6c 16 03 94 0f 5a |D.. ..0.Q.l....Z|
1112 1112 02d0: 46 93 7f 1c 87 8d 25 d7 9d a2 d1 92 4c f3 c2 54 |F.....%.....L..T|
1113 1113 02e0: ba f8 70 18 ca 24 0a 29 96 43 71 f2 93 95 74 18 |..p..$.).Cq...t.|
1114 1114 02f0: b5 65 c4 b8 f6 6c 5c 34 20 1e d5 0c 21 c0 b1 90 |.e...l\4 ...!...|
1115 1115 0300: 9e 12 40 b9 18 fa 5a 00 41 a2 39 d3 a9 c1 73 21 |..@...Z.A.9...s!|
1116 1116 0310: 8e 5e 3c b9 b8 f8 48 6a 76 46 a7 1a b6 dd 5b 51 |.^<...HjvF....[Q|
1117 1117 0320: 5e 19 1d 59 12 c6 32 89 02 9a c0 8f 4f b8 0a ba |^..Y..2.....O...|
1118 1118 0330: 5e ec 58 37 44 a3 2f dd 33 ed c9 d3 dd c7 22 1b |^.X7D./.3.....".|
1119 1119 0340: 2f d4 94 8e 95 3f 77 a7 ae 6e f3 32 8d bb 4a 4c |/....?w..n.2..JL|
1120 1120 0350: b8 0a 5a 43 34 3a b3 3a d6 77 ff 5c b6 fa ad f9 |..ZC4:.:.w.\....|
1121 1121 0360: db fb 6a 33 df c1 7d 99 cf ef d4 d5 6d da 77 7c |..j3..}.....m.w||
1122 1122 0370: 3b 19 fd af c5 3f f1 60 c3 17 |;....?.`..|
1123 1123 $ hg debugbundle ../rev.hg2.bz
1124 1124 Stream params: {Compression: GZ}
1125 changegroup -- {}
1125 changegroup -- {} (mandatory: False)
1126 1126 32af7686d403cf45b5d95f2d70cebea587ac806a
1127 1127 9520eea781bcca16c1e15acc0ba14335a0e8e5ba
1128 1128 eea13746799a9e0bfd88f29d3c2e9dc9389f524f
1129 1129 02de42196ebee42ef284b6780a87cdc96e8eaab6
1130 1130 $ hg unbundle ../rev.hg2.bz
1131 1131 adding changesets
1132 1132 adding manifests
1133 1133 adding file changes
1134 1134 added 0 changesets with 0 changes to 3 files
1135 1135 (run 'hg update' to get a working copy)
1136 1136 Simple case where it just work: BZ
1137 1137 ----------------------------------
1138 1138
1139 1139 $ hg bundle2 --compress BZ --rev '8+7+5+4' ../rev.hg2.bz
1140 1140 $ f --hexdump ../rev.hg2.bz
1141 1141 ../rev.hg2.bz:
1142 1142 0000: 48 47 32 30 00 00 00 0e 43 6f 6d 70 72 65 73 73 |HG20....Compress|
1143 1143 0010: 69 6f 6e 3d 42 5a 42 5a 68 39 31 41 59 26 53 59 |ion=BZBZh91AY&SY|
1144 1144 0020: a3 4b 18 3d 00 00 1a 7f ff ff bf 5f f6 ef ef 7f |.K.=......._....|
1145 1145 0030: f6 3f f7 d1 d9 ff ff f7 6e ff ff 6e f7 f6 bd df |.?......n..n....|
1146 1146 0040: b5 ab ff cf 67 f6 e7 7b f7 c0 02 d7 33 82 8b 51 |....g..{....3..Q|
1147 1147 0050: 04 a5 53 d5 3d 27 a0 99 18 4d 0d 34 00 d1 a1 e8 |..S.='...M.4....|
1148 1148 0060: 80 c8 7a 87 a9 a3 43 6a 3d 46 86 26 80 34 3d 40 |..z...Cj=F.&.4=@|
1149 1149 0070: c8 c9 b5 34 f4 8f 48 0f 51 ea 34 34 fd 4d aa 19 |...4..H.Q.44.M..|
1150 1150 0080: 03 40 0c 08 da 86 43 d4 f5 0f 42 1e a0 f3 54 33 |.@....C...B...T3|
1151 1151 0090: 54 d3 13 4d 03 40 32 00 00 32 03 26 80 0d 00 0d |T..M.@2..2.&....|
1152 1152 00a0: 00 68 c8 c8 03 20 32 30 98 8c 80 00 00 03 4d 00 |.h... 20......M.|
1153 1153 00b0: c8 00 00 0d 00 00 22 99 a1 34 c2 64 a6 d5 34 1a |......"..4.d..4.|
1154 1154 00c0: 00 00 06 86 83 4d 07 a8 d1 a0 68 01 a0 00 00 00 |.....M....h.....|
1155 1155 00d0: 00 0d 06 80 00 00 00 0d 00 03 40 00 00 04 a4 a1 |..........@.....|
1156 1156 00e0: 4d a9 89 89 b4 9a 32 0c 43 46 86 87 a9 8d 41 9a |M.....2.CF....A.|
1157 1157 00f0: 98 46 9a 0d 31 32 1a 34 0d 0c 8d a2 0c 98 4d 06 |.F..12.4......M.|
1158 1158 0100: 8c 40 c2 60 8d 0d 0c 20 c9 89 fa a0 d0 d3 21 a1 |.@.`... ......!.|
1159 1159 0110: ea 34 d3 68 9e a6 d1 74 05 33 cb 66 96 93 28 64 |.4.h...t.3.f..(d|
1160 1160 0120: 40 91 22 ac 55 9b ea 40 7b 38 94 e2 f8 06 00 cb |@.".U..@{8......|
1161 1161 0130: 28 02 00 4d ab 40 24 10 43 18 cf 64 b4 06 83 0c |(..M.@$.C..d....|
1162 1162 0140: 34 6c b4 a3 d4 0a 0a e4 a8 5c 4e 23 c0 c9 7a 31 |4l.......\N#..z1|
1163 1163 0150: 97 87 77 7a 64 88 80 8e 60 97 20 93 0f 8e eb c4 |..wzd...`. .....|
1164 1164 0160: 62 a4 44 a3 52 20 b2 99 a9 2e e1 d7 29 4a 54 ac |b.D.R ......)JT.|
1165 1165 0170: 44 7a bb cc 04 3d e0 aa bd 6a 33 5e 9b a2 57 36 |Dz...=...j3^..W6|
1166 1166 0180: fa cb 45 bb 6d 3e c1 d9 d9 f5 83 69 8a d0 e0 e2 |..E.m>.....i....|
1167 1167 0190: e7 ae 90 55 24 da 3f ab 78 c0 4c b4 56 a3 9e a4 |...U$.?.x.L.V...|
1168 1168 01a0: af 9c 65 74 86 ec 6d dc 62 dc 33 ca c8 50 dd 9d |..et..m.b.3..P..|
1169 1169 01b0: 98 8e 9e 59 20 f3 f0 42 91 4a 09 f5 75 8d 3d a5 |...Y ..B.J..u.=.|
1170 1170 01c0: a5 15 cb 8d 10 63 b0 c2 2e b2 81 f7 c1 76 0e 53 |.....c.......v.S|
1171 1171 01d0: 6c 0e 46 73 b5 ae 67 f9 4c 0b 45 6b a8 32 2a 2f |l.Fs..g.L.Ek.2*/|
1172 1172 01e0: a2 54 a4 44 05 20 a1 38 d1 a4 c6 09 a8 2b 08 99 |.T.D. .8.....+..|
1173 1173 01f0: a4 14 ae 8d a3 e3 aa 34 27 d8 44 ca c3 5d 21 8b |.......4'.D..]!.|
1174 1174 0200: 1a 1e 97 29 71 2b 09 4a 4a 55 55 94 58 65 b2 bc |...)q+.JJUU.Xe..|
1175 1175 0210: f3 a5 90 26 36 76 67 7a 51 98 d6 8a 4a 99 50 b5 |...&6vgzQ...J.P.|
1176 1176 0220: 99 8f 94 21 17 a9 8b f3 ad 4c 33 d4 2e 40 c8 0c |...!.....L3..@..|
1177 1177 0230: 3b 90 53 39 db 48 02 34 83 48 d6 b3 99 13 d2 58 |;.S9.H.4.H.....X|
1178 1178 0240: 65 8e 71 ac a9 06 95 f2 c4 8e b4 08 6b d3 0c ae |e.q.........k...|
1179 1179 0250: d9 90 56 71 43 a7 a2 62 16 3e 50 63 d3 57 3c 2d |..VqC..b.>Pc.W<-|
1180 1180 0260: 9f 0f 34 05 08 d8 a6 4b 59 31 54 66 3a 45 0c 8a |..4....KY1Tf:E..|
1181 1181 0270: c7 90 3a f0 6a 83 1b f5 ca fb 80 2b 50 06 fb 51 |..:.j......+P..Q|
1182 1182 0280: 7e a6 a4 d4 81 44 82 21 54 00 5b 1a 30 83 62 a3 |~....D.!T.[.0.b.|
1183 1183 0290: 18 b6 24 19 1e 45 df 4d 5c db a6 af 5b ac 90 fa |..$..E.M\...[...|
1184 1184 02a0: 3e ed f9 ec 4c ba 36 ee d8 60 20 a7 c7 3b cb d1 |>...L.6..` ..;..|
1185 1185 02b0: 90 43 7d 27 16 50 5d ad f4 14 07 0b 90 5c cc 6b |.C}'.P]......\.k|
1186 1186 02c0: 8d 3f a6 88 f4 34 37 a8 cf 14 63 36 19 f7 3e 28 |.?...47...c6..>(|
1187 1187 02d0: de 99 e8 16 a4 9d 0d 40 a1 a7 24 52 14 a6 72 62 |.......@..$R..rb|
1188 1188 02e0: 59 5a ca 2d e5 51 90 78 88 d9 c6 c7 21 d0 f7 46 |YZ.-.Q.x....!..F|
1189 1189 02f0: b2 04 46 44 4e 20 9c 12 b1 03 4e 25 e0 a9 0c 58 |..FDN ....N%...X|
1190 1190 0300: 5b 1d 3c 93 20 01 51 de a9 1c 69 23 32 46 14 b4 |[.<. .Q...i#2F..|
1191 1191 0310: 90 db 17 98 98 50 03 90 29 aa 40 b0 13 d8 43 d2 |.....P..).@...C.|
1192 1192 0320: 5f c5 9d eb f3 f2 ad 41 e8 7a a9 ed a1 58 84 a6 |_......A.z...X..|
1193 1193 0330: 42 bf d6 fc 24 82 c1 20 32 26 4a 15 a6 1d 29 7f |B...$.. 2&J...).|
1194 1194 0340: 7e f4 3d 07 bc 62 9a 5b ec 44 3d 72 1d 41 8b 5c |~.=..b.[.D=r.A.\|
1195 1195 0350: 80 de 0e 62 9a 2e f8 83 00 d5 07 a0 9c c6 74 98 |...b..........t.|
1196 1196 0360: 11 b2 5e a9 38 02 03 ee fd 86 5c f4 86 b3 ae da |..^.8.....\.....|
1197 1197 0370: 05 94 01 c5 c6 ea 18 e6 ba 2a ba b3 04 5c 96 89 |.........*...\..|
1198 1198 0380: 72 63 5b 10 11 f6 67 34 98 cb e4 c0 4e fa e6 99 |rc[...g4....N...|
1199 1199 0390: 19 6e 50 e8 26 8d 0c 17 e0 be ef e1 8e 02 6f 32 |.nP.&.........o2|
1200 1200 03a0: 82 dc 26 f8 a1 08 f3 8a 0d f3 c4 75 00 48 73 b8 |..&........u.Hs.|
1201 1201 03b0: be 3b 0d 7f d0 fd c7 78 96 ec e0 03 80 68 4d 8d |.;.....x.....hM.|
1202 1202 03c0: 43 8c d7 68 58 f9 50 f0 18 cb 21 58 1b 60 cd 1f |C..hX.P...!X.`..|
1203 1203 03d0: 84 36 2e 16 1f 0a f7 4e 8f eb df 01 2d c2 79 0b |.6.....N....-.y.|
1204 1204 03e0: f7 24 ea 0d e8 59 86 51 6e 1c 30 a3 ad 2f ee 8c |.$...Y.Qn.0../..|
1205 1205 03f0: 90 c8 84 d5 e8 34 c1 95 b2 c9 f6 4d 87 1c 7d 19 |.....4.....M..}.|
1206 1206 0400: d6 41 58 56 7a e0 6c ba 10 c7 e8 33 39 36 96 e7 |.AXVz.l....396..|
1207 1207 0410: d2 f9 59 9a 08 95 48 38 e7 0b b7 0a 24 67 c4 39 |..Y...H8....$g.9|
1208 1208 0420: 8b 43 88 57 9c 01 f5 61 b5 e1 27 41 7e af 83 fe |.C.W...a..'A~...|
1209 1209 0430: 2e e4 8a 70 a1 21 46 96 30 7a |...p.!F.0z|
1210 1210 $ hg debugbundle ../rev.hg2.bz
1211 1211 Stream params: {Compression: BZ}
1212 changegroup -- {}
1212 changegroup -- {} (mandatory: False)
1213 1213 32af7686d403cf45b5d95f2d70cebea587ac806a
1214 1214 9520eea781bcca16c1e15acc0ba14335a0e8e5ba
1215 1215 eea13746799a9e0bfd88f29d3c2e9dc9389f524f
1216 1216 02de42196ebee42ef284b6780a87cdc96e8eaab6
1217 1217 $ hg unbundle ../rev.hg2.bz
1218 1218 adding changesets
1219 1219 adding manifests
1220 1220 adding file changes
1221 1221 added 0 changesets with 0 changes to 3 files
1222 1222 (run 'hg update' to get a working copy)
1223 1223
1224 1224 unknown compression while unbundling
1225 1225 -----------------------------
1226 1226
1227 1227 $ hg bundle2 --param Compression=FooBarUnknown --rev '8+7+5+4' ../rev.hg2.bz
1228 1228 $ cat ../rev.hg2.bz | hg statbundle2
1229 1229 abort: unknown parameters: Stream Parameter - Compression='FooBarUnknown'
1230 1230 [255]
1231 1231 $ hg unbundle ../rev.hg2.bz
1232 1232 abort: ../rev.hg2.bz: unknown bundle feature, Stream Parameter - Compression='FooBarUnknown'
1233 1233 (see https://mercurial-scm.org/wiki/BundleFeature for more information)
1234 1234 [255]
1235 1235
1236 1236 $ cd ..
@@ -1,85 +1,85 b''
1 1
2 2 Create a test repository:
3 3
4 4 $ hg init repo
5 5 $ cd repo
6 6 $ touch a ; hg add a ; hg ci -ma
7 7 $ touch b ; hg add b ; hg ci -mb
8 8 $ touch c ; hg add c ; hg ci -mc
9 9 $ hg bundle --base 0 --rev tip bundle.hg -v --type v1
10 10 2 changesets found
11 11 uncompressed size of bundle content:
12 12 332 (changelog)
13 13 282 (manifests)
14 14 93 b
15 15 93 c
16 16 $ hg bundle --base 0 --rev tip bundle2.hg -v --type none-v2
17 17 2 changesets found
18 18 uncompressed size of bundle content:
19 19 344 (changelog)
20 20 322 (manifests)
21 21 113 b
22 22 113 c
23 23
24 24 Terse output:
25 25
26 26 $ hg debugbundle bundle.hg
27 27 0e067c57feba1a5694ca4844f05588bb1bf82342
28 28 991a3460af53952d10ec8a295d3d2cc2e5fa9690
29 29
30 30 Terse output:
31 31
32 32 $ hg debugbundle bundle2.hg
33 33 Stream params: {}
34 changegroup -- {nbchanges: 2, version: 02}
34 changegroup -- {nbchanges: 2, version: 02} (mandatory: True)
35 35 0e067c57feba1a5694ca4844f05588bb1bf82342
36 36 991a3460af53952d10ec8a295d3d2cc2e5fa9690
37 cache:rev-branch-cache -- {}
37 cache:rev-branch-cache -- {} (mandatory: True)
38 38
39 39 Quiet output
40 40
41 41 $ hg debugbundle --quiet bundle2.hg
42 42 Stream params: {}
43 changegroup -- {nbchanges: 2, version: 02}
44 cache:rev-branch-cache -- {}
43 changegroup -- {nbchanges: 2, version: 02} (mandatory: True)
44 cache:rev-branch-cache -- {} (mandatory: True)
45 45
46 46 Verbose output:
47 47
48 48 $ hg debugbundle --all bundle.hg
49 49 format: id, p1, p2, cset, delta base, len(delta)
50 50
51 51 changelog
52 52 0e067c57feba1a5694ca4844f05588bb1bf82342 3903775176ed42b1458a6281db4a0ccf4d9f287a 0000000000000000000000000000000000000000 0e067c57feba1a5694ca4844f05588bb1bf82342 3903775176ed42b1458a6281db4a0ccf4d9f287a 80
53 53 991a3460af53952d10ec8a295d3d2cc2e5fa9690 0e067c57feba1a5694ca4844f05588bb1bf82342 0000000000000000000000000000000000000000 991a3460af53952d10ec8a295d3d2cc2e5fa9690 0e067c57feba1a5694ca4844f05588bb1bf82342 80
54 54
55 55 manifest
56 56 686dbf0aeca417636fa26a9121c681eabbb15a20 8515d4bfda768e04af4c13a69a72e28c7effbea7 0000000000000000000000000000000000000000 0e067c57feba1a5694ca4844f05588bb1bf82342 8515d4bfda768e04af4c13a69a72e28c7effbea7 55
57 57 ae25a31b30b3490a981e7b96a3238cc69583fda1 686dbf0aeca417636fa26a9121c681eabbb15a20 0000000000000000000000000000000000000000 991a3460af53952d10ec8a295d3d2cc2e5fa9690 686dbf0aeca417636fa26a9121c681eabbb15a20 55
58 58
59 59 b
60 60 b80de5d138758541c5f05265ad144ab9fa86d1db 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 0e067c57feba1a5694ca4844f05588bb1bf82342 0000000000000000000000000000000000000000 0
61 61
62 62 c
63 63 b80de5d138758541c5f05265ad144ab9fa86d1db 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 991a3460af53952d10ec8a295d3d2cc2e5fa9690 0000000000000000000000000000000000000000 0
64 64
65 65 $ hg debugbundle --all bundle2.hg
66 66 Stream params: {}
67 changegroup -- {nbchanges: 2, version: 02}
67 changegroup -- {nbchanges: 2, version: 02} (mandatory: True)
68 68 format: id, p1, p2, cset, delta base, len(delta)
69 69
70 70 changelog
71 71 0e067c57feba1a5694ca4844f05588bb1bf82342 3903775176ed42b1458a6281db4a0ccf4d9f287a 0000000000000000000000000000000000000000 0e067c57feba1a5694ca4844f05588bb1bf82342 0000000000000000000000000000000000000000 66
72 72 991a3460af53952d10ec8a295d3d2cc2e5fa9690 0e067c57feba1a5694ca4844f05588bb1bf82342 0000000000000000000000000000000000000000 991a3460af53952d10ec8a295d3d2cc2e5fa9690 0000000000000000000000000000000000000000 66
73 73
74 74 manifest
75 75 686dbf0aeca417636fa26a9121c681eabbb15a20 8515d4bfda768e04af4c13a69a72e28c7effbea7 0000000000000000000000000000000000000000 0e067c57feba1a5694ca4844f05588bb1bf82342 8515d4bfda768e04af4c13a69a72e28c7effbea7 55
76 76 ae25a31b30b3490a981e7b96a3238cc69583fda1 686dbf0aeca417636fa26a9121c681eabbb15a20 0000000000000000000000000000000000000000 991a3460af53952d10ec8a295d3d2cc2e5fa9690 686dbf0aeca417636fa26a9121c681eabbb15a20 55
77 77
78 78 b
79 79 b80de5d138758541c5f05265ad144ab9fa86d1db 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 0e067c57feba1a5694ca4844f05588bb1bf82342 0000000000000000000000000000000000000000 0
80 80
81 81 c
82 82 b80de5d138758541c5f05265ad144ab9fa86d1db 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 991a3460af53952d10ec8a295d3d2cc2e5fa9690 0000000000000000000000000000000000000000 0
83 cache:rev-branch-cache -- {}
83 cache:rev-branch-cache -- {} (mandatory: True)
84 84
85 85 $ cd ..
@@ -1,358 +1,358 b''
1 1 #require no-reposimplestore
2 2
3 3 Check whether size of generaldelta revlog is not bigger than its
4 4 regular equivalent. Test would fail if generaldelta was naive
5 5 implementation of parentdelta: third manifest revision would be fully
6 6 inserted due to big distance from its paren revision (zero).
7 7
8 8 $ hg init repo --config format.generaldelta=no --config format.usegeneraldelta=no
9 9 $ cd repo
10 10 $ echo foo > foo
11 11 $ echo bar > bar
12 12 $ echo baz > baz
13 13 $ hg commit -q -Am boo
14 14 $ hg clone --pull . ../gdrepo -q --config format.generaldelta=yes
15 15 $ for r in 1 2 3; do
16 16 > echo $r > foo
17 17 > hg commit -q -m $r
18 18 > hg up -q -r 0
19 19 > hg pull . -q -r $r -R ../gdrepo
20 20 > done
21 21
22 22 $ cd ..
23 23 >>> from __future__ import print_function
24 24 >>> import os
25 25 >>> regsize = os.stat("repo/.hg/store/00manifest.i").st_size
26 26 >>> gdsize = os.stat("gdrepo/.hg/store/00manifest.i").st_size
27 27 >>> if regsize < gdsize:
28 28 ... print('generaldata increased size of manifest')
29 29
30 30 Verify rev reordering doesnt create invalid bundles (issue4462)
31 31 This requires a commit tree that when pulled will reorder manifest revs such
32 32 that the second manifest to create a file rev will be ordered before the first
33 33 manifest to create that file rev. We also need to do a partial pull to ensure
34 34 reordering happens. At the end we verify the linkrev points at the earliest
35 35 commit.
36 36
37 37 $ hg init server --config format.generaldelta=True
38 38 $ cd server
39 39 $ touch a
40 40 $ hg commit -Aqm a
41 41 $ echo x > x
42 42 $ echo y > y
43 43 $ hg commit -Aqm xy
44 44 $ hg up -q '.^'
45 45 $ echo x > x
46 46 $ echo z > z
47 47 $ hg commit -Aqm xz
48 48 $ hg up -q 1
49 49 $ echo b > b
50 50 $ hg commit -Aqm b
51 51 $ hg merge -q 2
52 52 $ hg commit -Aqm merge
53 53 $ echo c > c
54 54 $ hg commit -Aqm c
55 55 $ hg log -G -T '{rev} {shortest(node)} {desc}'
56 56 @ 5 ebb8 c
57 57 |
58 58 o 4 baf7 merge
59 59 |\
60 60 | o 3 a129 b
61 61 | |
62 62 o | 2 958c xz
63 63 | |
64 64 | o 1 f00c xy
65 65 |/
66 66 o 0 3903 a
67 67
68 68 $ cd ..
69 69 $ hg init client --config format.generaldelta=false --config format.usegeneraldelta=false
70 70 $ cd client
71 71 $ hg pull -q ../server -r 4
72 72 $ hg debugdeltachain x
73 73 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
74 74 0 1 1 -1 base 3 2 3 1.50000 3 0 0.00000
75 75
76 76 $ cd ..
77 77
78 78 Test "usegeneraldelta" config
79 79 (repo are general delta, but incoming bundle are not re-deltafied)
80 80
81 81 delta coming from the server base delta server are not recompressed.
82 82 (also include the aggressive version for comparison)
83 83
84 84 $ hg clone repo --pull --config format.usegeneraldelta=1 usegd
85 85 requesting all changes
86 86 adding changesets
87 87 adding manifests
88 88 adding file changes
89 89 added 4 changesets with 6 changes to 3 files (+2 heads)
90 90 new changesets 0ea3fcf9d01d:bba78d330d9c
91 91 updating to branch default
92 92 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
93 93 $ hg clone repo --pull --config format.generaldelta=1 full
94 94 requesting all changes
95 95 adding changesets
96 96 adding manifests
97 97 adding file changes
98 98 added 4 changesets with 6 changes to 3 files (+2 heads)
99 99 new changesets 0ea3fcf9d01d:bba78d330d9c
100 100 updating to branch default
101 101 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
102 102 $ hg -R repo debugdeltachain -m
103 103 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
104 104 0 1 1 -1 base 104 135 104 0.77037 104 0 0.00000
105 105 1 1 2 0 prev 57 135 161 1.19259 161 0 0.00000
106 106 2 1 3 1 prev 57 135 218 1.61481 218 0 0.00000
107 107 3 2 1 -1 base 104 135 104 0.77037 104 0 0.00000
108 108 $ hg -R usegd debugdeltachain -m
109 109 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
110 110 0 1 1 -1 base 104 135 104 0.77037 104 0 0.00000
111 111 1 1 2 0 p1 57 135 161 1.19259 161 0 0.00000
112 112 2 1 3 1 prev 57 135 218 1.61481 218 0 0.00000
113 113 3 1 2 0 p1 57 135 161 1.19259 275 114 0.70807
114 114 $ hg -R full debugdeltachain -m
115 115 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
116 116 0 1 1 -1 base 104 135 104 0.77037 104 0 0.00000
117 117 1 1 2 0 p1 57 135 161 1.19259 161 0 0.00000
118 118 2 1 2 0 p1 57 135 161 1.19259 218 57 0.35404
119 119 3 1 2 0 p1 57 135 161 1.19259 275 114 0.70807
120 120
121 121 Test format.aggressivemergedeltas
122 122
123 123 $ hg init --config format.generaldelta=1 aggressive
124 124 $ cd aggressive
125 125 $ cat << EOF >> .hg/hgrc
126 126 > [format]
127 127 > generaldelta = 1
128 128 > EOF
129 129 $ touch a b c d e
130 130 $ hg commit -Aqm side1
131 131 $ hg up -q null
132 132 $ touch x y
133 133 $ hg commit -Aqm side2
134 134
135 135 - Verify non-aggressive merge uses p1 (commit 1) as delta parent
136 136 $ hg merge -q 0
137 137 $ hg commit -q -m merge
138 138 $ hg debugdeltachain -m
139 139 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
140 140 0 1 1 -1 base 59 215 59 0.27442 59 0 0.00000
141 141 1 1 2 0 prev 61 86 120 1.39535 120 0 0.00000
142 142 2 1 3 1 p1 65 301 185 0.61462 185 0 0.00000
143 143
144 144 $ hg strip -q -r . --config extensions.strip=
145 145
146 146 - Verify aggressive merge uses p2 (commit 0) as delta parent
147 147 $ hg up -q -C 1
148 148 $ hg merge -q 0
149 149 $ hg commit -q -m merge --config format.aggressivemergedeltas=True
150 150 $ hg debugdeltachain -m
151 151 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
152 152 0 1 1 -1 base 59 215 59 0.27442 59 0 0.00000
153 153 1 1 2 0 prev 61 86 120 1.39535 120 0 0.00000
154 154 2 1 2 0 p2 62 301 121 0.40199 182 61 0.50413
155 155
156 156 Test that strip bundle use bundle2
157 157 $ hg --config extensions.strip= strip .
158 158 0 files updated, 0 files merged, 5 files removed, 0 files unresolved
159 159 saved backup bundle to $TESTTMP/aggressive/.hg/strip-backup/1c5d4dc9a8b8-6c68e60c-backup.hg
160 160 $ hg debugbundle .hg/strip-backup/*
161 161 Stream params: {Compression: BZ}
162 changegroup -- {nbchanges: 1, version: 02}
162 changegroup -- {nbchanges: 1, version: 02} (mandatory: True)
163 163 1c5d4dc9a8b8d6e1750966d343e94db665e7a1e9
164 cache:rev-branch-cache -- {}
165 phase-heads -- {}
164 cache:rev-branch-cache -- {} (mandatory: True)
165 phase-heads -- {} (mandatory: True)
166 166 1c5d4dc9a8b8d6e1750966d343e94db665e7a1e9 draft
167 167
168 168 $ cd ..
169 169
170 170 test maxdeltachainspan
171 171
172 172 $ hg init source-repo
173 173 $ cd source-repo
174 174 $ hg debugbuilddag --new-file '.+5:brancha$.+11:branchb$.+30:branchc<brancha+2<branchb+2'
175 175 $ cd ..
176 176 $ hg -R source-repo debugdeltachain -m
177 177 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
178 178 0 1 1 -1 base 46 45 46 1.02222 46 0 0.00000
179 179 1 1 2 0 p1 57 90 103 1.14444 103 0 0.00000
180 180 2 1 3 1 p1 57 135 160 1.18519 160 0 0.00000
181 181 3 1 4 2 p1 57 180 217 1.20556 217 0 0.00000
182 182 4 1 5 3 p1 57 225 274 1.21778 274 0 0.00000
183 183 5 1 6 4 p1 57 270 331 1.22593 331 0 0.00000
184 184 6 2 1 -1 base 46 45 46 1.02222 46 0 0.00000
185 185 7 2 2 6 p1 57 90 103 1.14444 103 0 0.00000
186 186 8 2 3 7 p1 57 135 160 1.18519 160 0 0.00000
187 187 9 2 4 8 p1 57 180 217 1.20556 217 0 0.00000
188 188 10 2 5 9 p1 58 226 275 1.21681 275 0 0.00000
189 189 11 2 6 10 p1 58 272 333 1.22426 333 0 0.00000
190 190 12 2 7 11 p1 58 318 391 1.22956 391 0 0.00000
191 191 13 2 8 12 p1 58 364 449 1.23352 449 0 0.00000
192 192 14 2 9 13 p1 58 410 507 1.23659 507 0 0.00000
193 193 15 2 10 14 p1 58 456 565 1.23904 565 0 0.00000
194 194 16 2 11 15 p1 58 502 623 1.24104 623 0 0.00000
195 195 17 2 12 16 p1 58 548 681 1.24270 681 0 0.00000
196 196 18 3 1 -1 base 47 46 47 1.02174 47 0 0.00000
197 197 19 3 2 18 p1 58 92 105 1.14130 105 0 0.00000
198 198 20 3 3 19 p1 58 138 163 1.18116 163 0 0.00000
199 199 21 3 4 20 p1 58 184 221 1.20109 221 0 0.00000
200 200 22 3 5 21 p1 58 230 279 1.21304 279 0 0.00000
201 201 23 3 6 22 p1 58 276 337 1.22101 337 0 0.00000
202 202 24 3 7 23 p1 58 322 395 1.22671 395 0 0.00000
203 203 25 3 8 24 p1 58 368 453 1.23098 453 0 0.00000
204 204 26 3 9 25 p1 58 414 511 1.23430 511 0 0.00000
205 205 27 3 10 26 p1 58 460 569 1.23696 569 0 0.00000
206 206 28 3 11 27 p1 58 506 627 1.23913 627 0 0.00000
207 207 29 3 12 28 p1 58 552 685 1.24094 685 0 0.00000
208 208 30 3 13 29 p1 58 598 743 1.24247 743 0 0.00000
209 209 31 3 14 30 p1 58 644 801 1.24379 801 0 0.00000
210 210 32 3 15 31 p1 58 690 859 1.24493 859 0 0.00000
211 211 33 3 16 32 p1 58 736 917 1.24592 917 0 0.00000
212 212 34 3 17 33 p1 58 782 975 1.24680 975 0 0.00000
213 213 35 3 18 34 p1 58 828 1033 1.24758 1033 0 0.00000
214 214 36 3 19 35 p1 58 874 1091 1.24828 1091 0 0.00000
215 215 37 3 20 36 p1 58 920 1149 1.24891 1149 0 0.00000
216 216 38 3 21 37 p1 58 966 1207 1.24948 1207 0 0.00000
217 217 39 3 22 38 p1 58 1012 1265 1.25000 1265 0 0.00000
218 218 40 3 23 39 p1 58 1058 1323 1.25047 1323 0 0.00000
219 219 41 3 24 40 p1 58 1104 1381 1.25091 1381 0 0.00000
220 220 42 3 25 41 p1 58 1150 1439 1.25130 1439 0 0.00000
221 221 43 3 26 42 p1 58 1196 1497 1.25167 1497 0 0.00000
222 222 44 3 27 43 p1 58 1242 1555 1.25201 1555 0 0.00000
223 223 45 3 28 44 p1 58 1288 1613 1.25233 1613 0 0.00000
224 224 46 3 29 45 p1 58 1334 1671 1.25262 1671 0 0.00000
225 225 47 3 30 46 p1 58 1380 1729 1.25290 1729 0 0.00000
226 226 48 3 31 47 p1 58 1426 1787 1.25316 1787 0 0.00000
227 227 49 4 1 -1 base 197 316 197 0.62342 197 0 0.00000
228 228 50 4 2 49 p1 58 362 255 0.70442 255 0 0.00000
229 229 51 4 3 50 prev 356 594 611 1.02862 611 0 0.00000
230 230 52 4 4 51 p1 58 640 669 1.04531 669 0 0.00000
231 231 $ hg clone --pull source-repo --config experimental.maxdeltachainspan=2800 relax-chain --config format.generaldelta=yes
232 232 requesting all changes
233 233 adding changesets
234 234 adding manifests
235 235 adding file changes
236 236 added 53 changesets with 53 changes to 53 files (+2 heads)
237 237 new changesets 61246295ee1e:99cae3713489
238 238 updating to branch default
239 239 14 files updated, 0 files merged, 0 files removed, 0 files unresolved
240 240 $ hg -R relax-chain debugdeltachain -m
241 241 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
242 242 0 1 1 -1 base 46 45 46 1.02222 46 0 0.00000
243 243 1 1 2 0 p1 57 90 103 1.14444 103 0 0.00000
244 244 2 1 3 1 p1 57 135 160 1.18519 160 0 0.00000
245 245 3 1 4 2 p1 57 180 217 1.20556 217 0 0.00000
246 246 4 1 5 3 p1 57 225 274 1.21778 274 0 0.00000
247 247 5 1 6 4 p1 57 270 331 1.22593 331 0 0.00000
248 248 6 2 1 -1 base 46 45 46 1.02222 46 0 0.00000
249 249 7 2 2 6 p1 57 90 103 1.14444 103 0 0.00000
250 250 8 2 3 7 p1 57 135 160 1.18519 160 0 0.00000
251 251 9 2 4 8 p1 57 180 217 1.20556 217 0 0.00000
252 252 10 2 5 9 p1 58 226 275 1.21681 275 0 0.00000
253 253 11 2 6 10 p1 58 272 333 1.22426 333 0 0.00000
254 254 12 2 7 11 p1 58 318 391 1.22956 391 0 0.00000
255 255 13 2 8 12 p1 58 364 449 1.23352 449 0 0.00000
256 256 14 2 9 13 p1 58 410 507 1.23659 507 0 0.00000
257 257 15 2 10 14 p1 58 456 565 1.23904 565 0 0.00000
258 258 16 2 11 15 p1 58 502 623 1.24104 623 0 0.00000
259 259 17 2 12 16 p1 58 548 681 1.24270 681 0 0.00000
260 260 18 3 1 -1 base 47 46 47 1.02174 47 0 0.00000
261 261 19 3 2 18 p1 58 92 105 1.14130 105 0 0.00000
262 262 20 3 3 19 p1 58 138 163 1.18116 163 0 0.00000
263 263 21 3 4 20 p1 58 184 221 1.20109 221 0 0.00000
264 264 22 3 5 21 p1 58 230 279 1.21304 279 0 0.00000
265 265 23 3 6 22 p1 58 276 337 1.22101 337 0 0.00000
266 266 24 3 7 23 p1 58 322 395 1.22671 395 0 0.00000
267 267 25 3 8 24 p1 58 368 453 1.23098 453 0 0.00000
268 268 26 3 9 25 p1 58 414 511 1.23430 511 0 0.00000
269 269 27 3 10 26 p1 58 460 569 1.23696 569 0 0.00000
270 270 28 3 11 27 p1 58 506 627 1.23913 627 0 0.00000
271 271 29 3 12 28 p1 58 552 685 1.24094 685 0 0.00000
272 272 30 3 13 29 p1 58 598 743 1.24247 743 0 0.00000
273 273 31 3 14 30 p1 58 644 801 1.24379 801 0 0.00000
274 274 32 3 15 31 p1 58 690 859 1.24493 859 0 0.00000
275 275 33 3 16 32 p1 58 736 917 1.24592 917 0 0.00000
276 276 34 3 17 33 p1 58 782 975 1.24680 975 0 0.00000
277 277 35 3 18 34 p1 58 828 1033 1.24758 1033 0 0.00000
278 278 36 3 19 35 p1 58 874 1091 1.24828 1091 0 0.00000
279 279 37 3 20 36 p1 58 920 1149 1.24891 1149 0 0.00000
280 280 38 3 21 37 p1 58 966 1207 1.24948 1207 0 0.00000
281 281 39 3 22 38 p1 58 1012 1265 1.25000 1265 0 0.00000
282 282 40 3 23 39 p1 58 1058 1323 1.25047 1323 0 0.00000
283 283 41 3 24 40 p1 58 1104 1381 1.25091 1381 0 0.00000
284 284 42 3 25 41 p1 58 1150 1439 1.25130 1439 0 0.00000
285 285 43 3 26 42 p1 58 1196 1497 1.25167 1497 0 0.00000
286 286 44 3 27 43 p1 58 1242 1555 1.25201 1555 0 0.00000
287 287 45 3 28 44 p1 58 1288 1613 1.25233 1613 0 0.00000
288 288 46 3 29 45 p1 58 1334 1671 1.25262 1671 0 0.00000
289 289 47 3 30 46 p1 58 1380 1729 1.25290 1729 0 0.00000
290 290 48 3 31 47 p1 58 1426 1787 1.25316 1787 0 0.00000
291 291 49 4 1 -1 base 197 316 197 0.62342 197 0 0.00000
292 292 50 4 2 49 p1 58 362 255 0.70442 255 0 0.00000
293 293 51 2 13 17 p1 58 594 739 1.24411 2781 2042 2.76319
294 294 52 5 1 -1 base 369 640 369 0.57656 369 0 0.00000
295 295 $ hg clone --pull source-repo --config experimental.maxdeltachainspan=0 noconst-chain --config format.generaldelta=yes
296 296 requesting all changes
297 297 adding changesets
298 298 adding manifests
299 299 adding file changes
300 300 added 53 changesets with 53 changes to 53 files (+2 heads)
301 301 new changesets 61246295ee1e:99cae3713489
302 302 updating to branch default
303 303 14 files updated, 0 files merged, 0 files removed, 0 files unresolved
304 304 $ hg -R noconst-chain debugdeltachain -m
305 305 rev chain# chainlen prev delta size rawsize chainsize ratio lindist extradist extraratio
306 306 0 1 1 -1 base 46 45 46 1.02222 46 0 0.00000
307 307 1 1 2 0 p1 57 90 103 1.14444 103 0 0.00000
308 308 2 1 3 1 p1 57 135 160 1.18519 160 0 0.00000
309 309 3 1 4 2 p1 57 180 217 1.20556 217 0 0.00000
310 310 4 1 5 3 p1 57 225 274 1.21778 274 0 0.00000
311 311 5 1 6 4 p1 57 270 331 1.22593 331 0 0.00000
312 312 6 2 1 -1 base 46 45 46 1.02222 46 0 0.00000
313 313 7 2 2 6 p1 57 90 103 1.14444 103 0 0.00000
314 314 8 2 3 7 p1 57 135 160 1.18519 160 0 0.00000
315 315 9 2 4 8 p1 57 180 217 1.20556 217 0 0.00000
316 316 10 2 5 9 p1 58 226 275 1.21681 275 0 0.00000
317 317 11 2 6 10 p1 58 272 333 1.22426 333 0 0.00000
318 318 12 2 7 11 p1 58 318 391 1.22956 391 0 0.00000
319 319 13 2 8 12 p1 58 364 449 1.23352 449 0 0.00000
320 320 14 2 9 13 p1 58 410 507 1.23659 507 0 0.00000
321 321 15 2 10 14 p1 58 456 565 1.23904 565 0 0.00000
322 322 16 2 11 15 p1 58 502 623 1.24104 623 0 0.00000
323 323 17 2 12 16 p1 58 548 681 1.24270 681 0 0.00000
324 324 18 3 1 -1 base 47 46 47 1.02174 47 0 0.00000
325 325 19 3 2 18 p1 58 92 105 1.14130 105 0 0.00000
326 326 20 3 3 19 p1 58 138 163 1.18116 163 0 0.00000
327 327 21 3 4 20 p1 58 184 221 1.20109 221 0 0.00000
328 328 22 3 5 21 p1 58 230 279 1.21304 279 0 0.00000
329 329 23 3 6 22 p1 58 276 337 1.22101 337 0 0.00000
330 330 24 3 7 23 p1 58 322 395 1.22671 395 0 0.00000
331 331 25 3 8 24 p1 58 368 453 1.23098 453 0 0.00000
332 332 26 3 9 25 p1 58 414 511 1.23430 511 0 0.00000
333 333 27 3 10 26 p1 58 460 569 1.23696 569 0 0.00000
334 334 28 3 11 27 p1 58 506 627 1.23913 627 0 0.00000
335 335 29 3 12 28 p1 58 552 685 1.24094 685 0 0.00000
336 336 30 3 13 29 p1 58 598 743 1.24247 743 0 0.00000
337 337 31 3 14 30 p1 58 644 801 1.24379 801 0 0.00000
338 338 32 3 15 31 p1 58 690 859 1.24493 859 0 0.00000
339 339 33 3 16 32 p1 58 736 917 1.24592 917 0 0.00000
340 340 34 3 17 33 p1 58 782 975 1.24680 975 0 0.00000
341 341 35 3 18 34 p1 58 828 1033 1.24758 1033 0 0.00000
342 342 36 3 19 35 p1 58 874 1091 1.24828 1091 0 0.00000
343 343 37 3 20 36 p1 58 920 1149 1.24891 1149 0 0.00000
344 344 38 3 21 37 p1 58 966 1207 1.24948 1207 0 0.00000
345 345 39 3 22 38 p1 58 1012 1265 1.25000 1265 0 0.00000
346 346 40 3 23 39 p1 58 1058 1323 1.25047 1323 0 0.00000
347 347 41 3 24 40 p1 58 1104 1381 1.25091 1381 0 0.00000
348 348 42 3 25 41 p1 58 1150 1439 1.25130 1439 0 0.00000
349 349 43 3 26 42 p1 58 1196 1497 1.25167 1497 0 0.00000
350 350 44 3 27 43 p1 58 1242 1555 1.25201 1555 0 0.00000
351 351 45 3 28 44 p1 58 1288 1613 1.25233 1613 0 0.00000
352 352 46 3 29 45 p1 58 1334 1671 1.25262 1671 0 0.00000
353 353 47 3 30 46 p1 58 1380 1729 1.25290 1729 0 0.00000
354 354 48 3 31 47 p1 58 1426 1787 1.25316 1787 0 0.00000
355 355 49 1 7 5 p1 58 316 389 1.23101 2857 2468 6.34447
356 356 50 1 8 49 p1 58 362 447 1.23481 2915 2468 5.52125
357 357 51 2 13 17 p1 58 594 739 1.24411 2642 1903 2.57510
358 358 52 2 14 51 p1 58 640 797 1.24531 2700 1903 2.38770
@@ -1,272 +1,272 b''
1 1 #require serve
2 2
3 3 = Test the getbundle() protocol function =
4 4
5 5 Create a test repository:
6 6
7 7 $ hg init repo
8 8 $ cd repo
9 9 $ hg debugbuilddag -n -m '+2 :fork +5 :p1 *fork +6 :p2 /p1 :m1 +3' > /dev/null
10 10 $ hg log -G --template '{node}\n'
11 11 o 10c14a2cc935e1d8c31f9e98587dcf27fb08a6da
12 12 |
13 13 o 4801a72e5d88cb515b0c7e40fae34180f3f837f2
14 14 |
15 15 o 0b2f73f04880d9cb6a5cd8a757f0db0ad01e32c3
16 16 |
17 17 o 8365676dbab05860ce0d9110f2af51368b961bbd
18 18 |\
19 19 | o 5686dbbd9fc46cb806599c878d02fe1cb56b83d3
20 20 | |
21 21 | o 13c0170174366b441dc68e8e33757232fa744458
22 22 | |
23 23 | o 63476832d8ec6558cf9bbe3cbe0c757e5cf18043
24 24 | |
25 25 | o 700b7e19db54103633c4bf4a6a6b6d55f4d50c03
26 26 | |
27 27 | o 928b5f94cdb278bb536eba552de348a4e92ef24d
28 28 | |
29 29 | o f34414c64173e0ecb61b25dc55e116dbbcc89bee
30 30 | |
31 31 | o 8931463777131cd73923e560b760061f2aa8a4bc
32 32 | |
33 33 o | 6621d79f61b23ec74cf4b69464343d9e0980ec8b
34 34 | |
35 35 o | bac16991d12ff45f9dc43c52da1946dfadb83e80
36 36 | |
37 37 o | ff42371d57168345fdf1a3aac66a51f6a45d41d2
38 38 | |
39 39 o | d5f6e1ea452285324836a49d7d3c2a63cfed1d31
40 40 | |
41 41 o | 713346a995c363120712aed1aee7e04afd867638
42 42 |/
43 43 o 29a4d1f17bd3f0779ca0525bebb1cfb51067c738
44 44 |
45 45 o 7704483d56b2a7b5db54dcee7c62378ac629b348
46 46
47 47 $ cd ..
48 48
49 49
50 50 = Test locally =
51 51
52 52 Get everything:
53 53
54 54 $ hg debuggetbundle repo bundle
55 55 $ hg debugbundle bundle
56 56 7704483d56b2a7b5db54dcee7c62378ac629b348
57 57 29a4d1f17bd3f0779ca0525bebb1cfb51067c738
58 58 713346a995c363120712aed1aee7e04afd867638
59 59 d5f6e1ea452285324836a49d7d3c2a63cfed1d31
60 60 ff42371d57168345fdf1a3aac66a51f6a45d41d2
61 61 bac16991d12ff45f9dc43c52da1946dfadb83e80
62 62 6621d79f61b23ec74cf4b69464343d9e0980ec8b
63 63 8931463777131cd73923e560b760061f2aa8a4bc
64 64 f34414c64173e0ecb61b25dc55e116dbbcc89bee
65 65 928b5f94cdb278bb536eba552de348a4e92ef24d
66 66 700b7e19db54103633c4bf4a6a6b6d55f4d50c03
67 67 63476832d8ec6558cf9bbe3cbe0c757e5cf18043
68 68 13c0170174366b441dc68e8e33757232fa744458
69 69 5686dbbd9fc46cb806599c878d02fe1cb56b83d3
70 70 8365676dbab05860ce0d9110f2af51368b961bbd
71 71 0b2f73f04880d9cb6a5cd8a757f0db0ad01e32c3
72 72 4801a72e5d88cb515b0c7e40fae34180f3f837f2
73 73 10c14a2cc935e1d8c31f9e98587dcf27fb08a6da
74 74
75 75 Get part of linear run:
76 76
77 77 $ hg debuggetbundle repo bundle -H 4801a72e5d88cb515b0c7e40fae34180f3f837f2 -C 8365676dbab05860ce0d9110f2af51368b961bbd
78 78 $ hg debugbundle bundle
79 79 0b2f73f04880d9cb6a5cd8a757f0db0ad01e32c3
80 80 4801a72e5d88cb515b0c7e40fae34180f3f837f2
81 81
82 82 Get missing branch and merge:
83 83
84 84 $ hg debuggetbundle repo bundle -H 4801a72e5d88cb515b0c7e40fae34180f3f837f2 -C 13c0170174366b441dc68e8e33757232fa744458
85 85 $ hg debugbundle bundle
86 86 713346a995c363120712aed1aee7e04afd867638
87 87 d5f6e1ea452285324836a49d7d3c2a63cfed1d31
88 88 ff42371d57168345fdf1a3aac66a51f6a45d41d2
89 89 bac16991d12ff45f9dc43c52da1946dfadb83e80
90 90 6621d79f61b23ec74cf4b69464343d9e0980ec8b
91 91 5686dbbd9fc46cb806599c878d02fe1cb56b83d3
92 92 8365676dbab05860ce0d9110f2af51368b961bbd
93 93 0b2f73f04880d9cb6a5cd8a757f0db0ad01e32c3
94 94 4801a72e5d88cb515b0c7e40fae34180f3f837f2
95 95
96 96 Get from only one head:
97 97
98 98 $ hg debuggetbundle repo bundle -H 928b5f94cdb278bb536eba552de348a4e92ef24d -C 29a4d1f17bd3f0779ca0525bebb1cfb51067c738
99 99 $ hg debugbundle bundle
100 100 8931463777131cd73923e560b760061f2aa8a4bc
101 101 f34414c64173e0ecb61b25dc55e116dbbcc89bee
102 102 928b5f94cdb278bb536eba552de348a4e92ef24d
103 103
104 104 Get parts of two branches:
105 105
106 106 $ hg debuggetbundle repo bundle -H 13c0170174366b441dc68e8e33757232fa744458 -C 700b7e19db54103633c4bf4a6a6b6d55f4d50c03 -H bac16991d12ff45f9dc43c52da1946dfadb83e80 -C d5f6e1ea452285324836a49d7d3c2a63cfed1d31
107 107 $ hg debugbundle bundle
108 108 ff42371d57168345fdf1a3aac66a51f6a45d41d2
109 109 bac16991d12ff45f9dc43c52da1946dfadb83e80
110 110 63476832d8ec6558cf9bbe3cbe0c757e5cf18043
111 111 13c0170174366b441dc68e8e33757232fa744458
112 112
113 113 Check that we get all needed file changes:
114 114
115 115 $ hg debugbundle bundle --all
116 116 format: id, p1, p2, cset, delta base, len(delta)
117 117
118 118 changelog
119 119 ff42371d57168345fdf1a3aac66a51f6a45d41d2 d5f6e1ea452285324836a49d7d3c2a63cfed1d31 0000000000000000000000000000000000000000 ff42371d57168345fdf1a3aac66a51f6a45d41d2 d5f6e1ea452285324836a49d7d3c2a63cfed1d31 99
120 120 bac16991d12ff45f9dc43c52da1946dfadb83e80 ff42371d57168345fdf1a3aac66a51f6a45d41d2 0000000000000000000000000000000000000000 bac16991d12ff45f9dc43c52da1946dfadb83e80 ff42371d57168345fdf1a3aac66a51f6a45d41d2 99
121 121 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 700b7e19db54103633c4bf4a6a6b6d55f4d50c03 0000000000000000000000000000000000000000 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 bac16991d12ff45f9dc43c52da1946dfadb83e80 102
122 122 13c0170174366b441dc68e8e33757232fa744458 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 0000000000000000000000000000000000000000 13c0170174366b441dc68e8e33757232fa744458 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 102
123 123
124 124 manifest
125 125 dac7984588fc4eea7acbf39693a9c1b06f5b175d 591f732a3faf1fb903815273f3c199a514a61ccb 0000000000000000000000000000000000000000 ff42371d57168345fdf1a3aac66a51f6a45d41d2 591f732a3faf1fb903815273f3c199a514a61ccb 113
126 126 0772616e6b48a76afb6c1458e193cbb3dae2e4ff dac7984588fc4eea7acbf39693a9c1b06f5b175d 0000000000000000000000000000000000000000 bac16991d12ff45f9dc43c52da1946dfadb83e80 dac7984588fc4eea7acbf39693a9c1b06f5b175d 113
127 127 eb498cd9af6c44108e43041e951ce829e29f6c80 bff2f4817ced57b386caf7c4e3e36a4bc9af7e93 0000000000000000000000000000000000000000 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 0772616e6b48a76afb6c1458e193cbb3dae2e4ff 295
128 128 b15709c071ddd2d93188508ba156196ab4f19620 eb498cd9af6c44108e43041e951ce829e29f6c80 0000000000000000000000000000000000000000 13c0170174366b441dc68e8e33757232fa744458 eb498cd9af6c44108e43041e951ce829e29f6c80 114
129 129
130 130 mf
131 131 4f73f97080266ab8e0c0561ca8d0da3eaf65b695 301ca08d026bb72cb4258a9d211bdf7ca0bcd810 0000000000000000000000000000000000000000 ff42371d57168345fdf1a3aac66a51f6a45d41d2 301ca08d026bb72cb4258a9d211bdf7ca0bcd810 17
132 132 c7b583de053293870e145f45bd2d61643563fd06 4f73f97080266ab8e0c0561ca8d0da3eaf65b695 0000000000000000000000000000000000000000 bac16991d12ff45f9dc43c52da1946dfadb83e80 4f73f97080266ab8e0c0561ca8d0da3eaf65b695 18
133 133 266ee3c0302a5a18f1cf96817ac79a51836179e9 edc0f6b8db80d68ae6aff2b19f7e5347ab68fa63 0000000000000000000000000000000000000000 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 c7b583de053293870e145f45bd2d61643563fd06 149
134 134 698c6a36220548cd3903ca7dada27c59aa500c52 266ee3c0302a5a18f1cf96817ac79a51836179e9 0000000000000000000000000000000000000000 13c0170174366b441dc68e8e33757232fa744458 266ee3c0302a5a18f1cf96817ac79a51836179e9 19
135 135
136 136 nf11
137 137 33fbc651630ffa7ccbebfe4eb91320a873e7291c 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 0000000000000000000000000000000000000000 16
138 138
139 139 nf12
140 140 ddce0544363f037e9fb889faca058f52dc01c0a5 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 13c0170174366b441dc68e8e33757232fa744458 0000000000000000000000000000000000000000 16
141 141
142 142 nf4
143 143 3c1407305701051cbed9f9cb9a68bdfb5997c235 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 ff42371d57168345fdf1a3aac66a51f6a45d41d2 0000000000000000000000000000000000000000 15
144 144
145 145 nf5
146 146 0dbd89c185f53a1727c54cd1ce256482fa23968e 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 bac16991d12ff45f9dc43c52da1946dfadb83e80 0000000000000000000000000000000000000000 15
147 147
148 148 Get branch and merge:
149 149
150 150 $ hg debuggetbundle repo bundle -C 7704483d56b2a7b5db54dcee7c62378ac629b348 -H 0b2f73f04880d9cb6a5cd8a757f0db0ad01e32c3
151 151 $ hg debugbundle bundle
152 152 29a4d1f17bd3f0779ca0525bebb1cfb51067c738
153 153 713346a995c363120712aed1aee7e04afd867638
154 154 d5f6e1ea452285324836a49d7d3c2a63cfed1d31
155 155 ff42371d57168345fdf1a3aac66a51f6a45d41d2
156 156 bac16991d12ff45f9dc43c52da1946dfadb83e80
157 157 6621d79f61b23ec74cf4b69464343d9e0980ec8b
158 158 8931463777131cd73923e560b760061f2aa8a4bc
159 159 f34414c64173e0ecb61b25dc55e116dbbcc89bee
160 160 928b5f94cdb278bb536eba552de348a4e92ef24d
161 161 700b7e19db54103633c4bf4a6a6b6d55f4d50c03
162 162 63476832d8ec6558cf9bbe3cbe0c757e5cf18043
163 163 13c0170174366b441dc68e8e33757232fa744458
164 164 5686dbbd9fc46cb806599c878d02fe1cb56b83d3
165 165 8365676dbab05860ce0d9110f2af51368b961bbd
166 166 0b2f73f04880d9cb6a5cd8a757f0db0ad01e32c3
167 167
168 168 = Test bundle2 =
169 169
170 170 $ hg debuggetbundle repo bundle -t bundle2
171 171 $ hg debugbundle bundle
172 172 Stream params: {}
173 changegroup -- {version: 01}
173 changegroup -- {version: 01} (mandatory: True)
174 174 7704483d56b2a7b5db54dcee7c62378ac629b348
175 175 29a4d1f17bd3f0779ca0525bebb1cfb51067c738
176 176 713346a995c363120712aed1aee7e04afd867638
177 177 d5f6e1ea452285324836a49d7d3c2a63cfed1d31
178 178 ff42371d57168345fdf1a3aac66a51f6a45d41d2
179 179 bac16991d12ff45f9dc43c52da1946dfadb83e80
180 180 6621d79f61b23ec74cf4b69464343d9e0980ec8b
181 181 8931463777131cd73923e560b760061f2aa8a4bc
182 182 f34414c64173e0ecb61b25dc55e116dbbcc89bee
183 183 928b5f94cdb278bb536eba552de348a4e92ef24d
184 184 700b7e19db54103633c4bf4a6a6b6d55f4d50c03
185 185 63476832d8ec6558cf9bbe3cbe0c757e5cf18043
186 186 13c0170174366b441dc68e8e33757232fa744458
187 187 5686dbbd9fc46cb806599c878d02fe1cb56b83d3
188 188 8365676dbab05860ce0d9110f2af51368b961bbd
189 189 0b2f73f04880d9cb6a5cd8a757f0db0ad01e32c3
190 190 4801a72e5d88cb515b0c7e40fae34180f3f837f2
191 191 10c14a2cc935e1d8c31f9e98587dcf27fb08a6da
192 192 = Test via HTTP =
193 193
194 194 Get everything:
195 195
196 196 $ hg serve -R repo -p $HGPORT -d --pid-file=hg.pid -E error.log -A access.log
197 197 $ cat hg.pid >> $DAEMON_PIDS
198 198 $ hg debuggetbundle http://localhost:$HGPORT/ bundle
199 199 $ hg debugbundle bundle
200 200 7704483d56b2a7b5db54dcee7c62378ac629b348
201 201 29a4d1f17bd3f0779ca0525bebb1cfb51067c738
202 202 713346a995c363120712aed1aee7e04afd867638
203 203 d5f6e1ea452285324836a49d7d3c2a63cfed1d31
204 204 ff42371d57168345fdf1a3aac66a51f6a45d41d2
205 205 bac16991d12ff45f9dc43c52da1946dfadb83e80
206 206 6621d79f61b23ec74cf4b69464343d9e0980ec8b
207 207 8931463777131cd73923e560b760061f2aa8a4bc
208 208 f34414c64173e0ecb61b25dc55e116dbbcc89bee
209 209 928b5f94cdb278bb536eba552de348a4e92ef24d
210 210 700b7e19db54103633c4bf4a6a6b6d55f4d50c03
211 211 63476832d8ec6558cf9bbe3cbe0c757e5cf18043
212 212 13c0170174366b441dc68e8e33757232fa744458
213 213 5686dbbd9fc46cb806599c878d02fe1cb56b83d3
214 214 8365676dbab05860ce0d9110f2af51368b961bbd
215 215 0b2f73f04880d9cb6a5cd8a757f0db0ad01e32c3
216 216 4801a72e5d88cb515b0c7e40fae34180f3f837f2
217 217 10c14a2cc935e1d8c31f9e98587dcf27fb08a6da
218 218
219 219 Get parts of two branches:
220 220
221 221 $ hg debuggetbundle http://localhost:$HGPORT/ bundle -H 13c0170174366b441dc68e8e33757232fa744458 -C 700b7e19db54103633c4bf4a6a6b6d55f4d50c03 -H bac16991d12ff45f9dc43c52da1946dfadb83e80 -C d5f6e1ea452285324836a49d7d3c2a63cfed1d31
222 222 $ hg debugbundle bundle
223 223 ff42371d57168345fdf1a3aac66a51f6a45d41d2
224 224 bac16991d12ff45f9dc43c52da1946dfadb83e80
225 225 63476832d8ec6558cf9bbe3cbe0c757e5cf18043
226 226 13c0170174366b441dc68e8e33757232fa744458
227 227
228 228 Check that we get all needed file changes:
229 229
230 230 $ hg debugbundle bundle --all
231 231 format: id, p1, p2, cset, delta base, len(delta)
232 232
233 233 changelog
234 234 ff42371d57168345fdf1a3aac66a51f6a45d41d2 d5f6e1ea452285324836a49d7d3c2a63cfed1d31 0000000000000000000000000000000000000000 ff42371d57168345fdf1a3aac66a51f6a45d41d2 d5f6e1ea452285324836a49d7d3c2a63cfed1d31 99
235 235 bac16991d12ff45f9dc43c52da1946dfadb83e80 ff42371d57168345fdf1a3aac66a51f6a45d41d2 0000000000000000000000000000000000000000 bac16991d12ff45f9dc43c52da1946dfadb83e80 ff42371d57168345fdf1a3aac66a51f6a45d41d2 99
236 236 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 700b7e19db54103633c4bf4a6a6b6d55f4d50c03 0000000000000000000000000000000000000000 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 bac16991d12ff45f9dc43c52da1946dfadb83e80 102
237 237 13c0170174366b441dc68e8e33757232fa744458 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 0000000000000000000000000000000000000000 13c0170174366b441dc68e8e33757232fa744458 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 102
238 238
239 239 manifest
240 240 dac7984588fc4eea7acbf39693a9c1b06f5b175d 591f732a3faf1fb903815273f3c199a514a61ccb 0000000000000000000000000000000000000000 ff42371d57168345fdf1a3aac66a51f6a45d41d2 591f732a3faf1fb903815273f3c199a514a61ccb 113
241 241 0772616e6b48a76afb6c1458e193cbb3dae2e4ff dac7984588fc4eea7acbf39693a9c1b06f5b175d 0000000000000000000000000000000000000000 bac16991d12ff45f9dc43c52da1946dfadb83e80 dac7984588fc4eea7acbf39693a9c1b06f5b175d 113
242 242 eb498cd9af6c44108e43041e951ce829e29f6c80 bff2f4817ced57b386caf7c4e3e36a4bc9af7e93 0000000000000000000000000000000000000000 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 0772616e6b48a76afb6c1458e193cbb3dae2e4ff 295
243 243 b15709c071ddd2d93188508ba156196ab4f19620 eb498cd9af6c44108e43041e951ce829e29f6c80 0000000000000000000000000000000000000000 13c0170174366b441dc68e8e33757232fa744458 eb498cd9af6c44108e43041e951ce829e29f6c80 114
244 244
245 245 mf
246 246 4f73f97080266ab8e0c0561ca8d0da3eaf65b695 301ca08d026bb72cb4258a9d211bdf7ca0bcd810 0000000000000000000000000000000000000000 ff42371d57168345fdf1a3aac66a51f6a45d41d2 301ca08d026bb72cb4258a9d211bdf7ca0bcd810 17
247 247 c7b583de053293870e145f45bd2d61643563fd06 4f73f97080266ab8e0c0561ca8d0da3eaf65b695 0000000000000000000000000000000000000000 bac16991d12ff45f9dc43c52da1946dfadb83e80 4f73f97080266ab8e0c0561ca8d0da3eaf65b695 18
248 248 266ee3c0302a5a18f1cf96817ac79a51836179e9 edc0f6b8db80d68ae6aff2b19f7e5347ab68fa63 0000000000000000000000000000000000000000 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 c7b583de053293870e145f45bd2d61643563fd06 149
249 249 698c6a36220548cd3903ca7dada27c59aa500c52 266ee3c0302a5a18f1cf96817ac79a51836179e9 0000000000000000000000000000000000000000 13c0170174366b441dc68e8e33757232fa744458 266ee3c0302a5a18f1cf96817ac79a51836179e9 19
250 250
251 251 nf11
252 252 33fbc651630ffa7ccbebfe4eb91320a873e7291c 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 63476832d8ec6558cf9bbe3cbe0c757e5cf18043 0000000000000000000000000000000000000000 16
253 253
254 254 nf12
255 255 ddce0544363f037e9fb889faca058f52dc01c0a5 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 13c0170174366b441dc68e8e33757232fa744458 0000000000000000000000000000000000000000 16
256 256
257 257 nf4
258 258 3c1407305701051cbed9f9cb9a68bdfb5997c235 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 ff42371d57168345fdf1a3aac66a51f6a45d41d2 0000000000000000000000000000000000000000 15
259 259
260 260 nf5
261 261 0dbd89c185f53a1727c54cd1ce256482fa23968e 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 bac16991d12ff45f9dc43c52da1946dfadb83e80 0000000000000000000000000000000000000000 15
262 262
263 263 Verify we hit the HTTP server:
264 264
265 265 $ cat access.log
266 266 * - - [*] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
267 267 $LOCALIP - - [$LOGDATE$] "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
268 268 * - - [*] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
269 269 $LOCALIP - - [$LOGDATE$] "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:common=700b7e19db54103633c4bf4a6a6b6d55f4d50c03+d5f6e1ea452285324836a49d7d3c2a63cfed1d31&heads=13c0170174366b441dc68e8e33757232fa744458+bac16991d12ff45f9dc43c52da1946dfadb83e80 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
270 270
271 271 $ cat error.log
272 272
@@ -1,181 +1,181 b''
1 1 Test changesets filtering during exchanges (some tests are still in
2 2 test-obsolete.t)
3 3
4 4 $ cat >> $HGRCPATH << EOF
5 5 > [experimental]
6 6 > evolution.createmarkers=True
7 7 > EOF
8 8
9 9 Push does not corrupt remote
10 10 ----------------------------
11 11
12 12 Create a DAG where a changeset reuses a revision from a file first used in an
13 13 extinct changeset.
14 14
15 15 $ hg init local
16 16 $ cd local
17 17 $ echo 'base' > base
18 18 $ hg commit -Am base
19 19 adding base
20 20 $ echo 'A' > A
21 21 $ hg commit -Am A
22 22 adding A
23 23 $ hg up 0
24 24 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
25 25 $ hg revert -ar 1
26 26 adding A
27 27 $ hg commit -Am "A'"
28 28 created new head
29 29 $ hg log -G --template='{desc} {node}'
30 30 @ A' f89bcc95eba5174b1ccc3e33a82e84c96e8338ee
31 31 |
32 32 | o A 9d73aac1b2ed7d53835eaeec212ed41ea47da53a
33 33 |/
34 34 o base d20a80d4def38df63a4b330b7fb688f3d4cae1e3
35 35
36 36 $ hg debugobsolete 9d73aac1b2ed7d53835eaeec212ed41ea47da53a f89bcc95eba5174b1ccc3e33a82e84c96e8338ee
37 37 obsoleted 1 changesets
38 38
39 39 Push it. The bundle should not refer to the extinct changeset.
40 40
41 41 $ hg init ../other
42 42 $ hg push ../other
43 43 pushing to ../other
44 44 searching for changes
45 45 adding changesets
46 46 adding manifests
47 47 adding file changes
48 48 added 2 changesets with 2 changes to 2 files
49 49 $ hg -R ../other verify
50 50 checking changesets
51 51 checking manifests
52 52 crosschecking files in changesets and manifests
53 53 checking files
54 54 2 files, 2 changesets, 2 total revisions
55 55
56 56 Adding a changeset going extinct locally
57 57 ------------------------------------------
58 58
59 59 Pull a changeset that will immediatly goes extinct (because you already have a
60 60 marker to obsolete him)
61 61 (test resolution of issue3788)
62 62
63 63 $ hg phase --draft --force f89bcc95eba5
64 64 $ hg phase -R ../other --draft --force f89bcc95eba5
65 65 $ hg commit --amend -m "A''"
66 66 $ hg --hidden --config extensions.mq= strip --no-backup f89bcc95eba5
67 67 $ hg pull ../other
68 68 pulling from ../other
69 69 searching for changes
70 70 adding changesets
71 71 adding manifests
72 72 adding file changes
73 73 added 1 changesets with 0 changes to 1 files (+1 heads)
74 74 1 new phase-divergent changesets
75 75 new changesets f89bcc95eba5
76 76 (run 'hg heads' to see heads, 'hg merge' to merge)
77 77
78 78 check that bundle is not affected
79 79
80 80 $ hg bundle --hidden --rev f89bcc95eba5 --base "f89bcc95eba5^" ../f89bcc95eba5.hg
81 81 1 changesets found
82 82 $ hg --hidden --config extensions.mq= strip --no-backup f89bcc95eba5
83 83 $ hg unbundle ../f89bcc95eba5.hg
84 84 adding changesets
85 85 adding manifests
86 86 adding file changes
87 87 added 1 changesets with 0 changes to 1 files (+1 heads)
88 88 (run 'hg heads' to see heads)
89 89
90 90 check-that bundle can contain markers:
91 91
92 92 $ hg bundle --hidden --rev f89bcc95eba5 --base "f89bcc95eba5^" ../f89bcc95eba5-obs.hg --config experimental.evolution.bundle-obsmarker=1
93 93 1 changesets found
94 94 $ hg debugbundle ../f89bcc95eba5.hg
95 95 Stream params: {Compression: BZ}
96 changegroup -- {nbchanges: 1, version: 02}
96 changegroup -- {nbchanges: 1, version: 02} (mandatory: True)
97 97 f89bcc95eba5174b1ccc3e33a82e84c96e8338ee
98 cache:rev-branch-cache -- {}
98 cache:rev-branch-cache -- {} (mandatory: True)
99 99 $ hg debugbundle ../f89bcc95eba5-obs.hg
100 100 Stream params: {Compression: BZ}
101 changegroup -- {nbchanges: 1, version: 02}
101 changegroup -- {nbchanges: 1, version: 02} (mandatory: True)
102 102 f89bcc95eba5174b1ccc3e33a82e84c96e8338ee
103 cache:rev-branch-cache -- {}
104 obsmarkers -- {}
103 cache:rev-branch-cache -- {} (mandatory: True)
104 obsmarkers -- {} (mandatory: True)
105 105 version: 1 (70 bytes)
106 106 9d73aac1b2ed7d53835eaeec212ed41ea47da53a f89bcc95eba5174b1ccc3e33a82e84c96e8338ee 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
107 107
108 108 $ cd ..
109 109
110 110 pull does not fetch excessive changesets when common node is hidden (issue4982)
111 111 -------------------------------------------------------------------------------
112 112
113 113 initial repo with server and client matching
114 114
115 115 $ hg init pull-hidden-common
116 116 $ cd pull-hidden-common
117 117 $ touch foo
118 118 $ hg -q commit -A -m initial
119 119 $ echo 1 > foo
120 120 $ hg commit -m 1
121 121 $ echo 2a > foo
122 122 $ hg commit -m 2a
123 123 $ cd ..
124 124 $ hg clone --pull pull-hidden-common pull-hidden-common-client
125 125 requesting all changes
126 126 adding changesets
127 127 adding manifests
128 128 adding file changes
129 129 added 3 changesets with 3 changes to 1 files
130 130 new changesets 96ee1d7354c4:6a29ed9c68de
131 131 updating to branch default
132 132 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
133 133
134 134 server obsoletes the old head
135 135
136 136 $ cd pull-hidden-common
137 137 $ hg -q up -r 1
138 138 $ echo 2b > foo
139 139 $ hg -q commit -m 2b
140 140 $ hg debugobsolete 6a29ed9c68defff1a139e5c6fa9696fb1a75783d bec0734cd68e84477ba7fc1d13e6cff53ab70129
141 141 obsoleted 1 changesets
142 142 $ cd ..
143 143
144 144 client only pulls down 1 changeset
145 145
146 146 $ cd pull-hidden-common-client
147 147 $ hg pull --debug
148 148 pulling from $TESTTMP/pull-hidden-common
149 149 query 1; heads
150 150 searching for changes
151 151 taking quick initial sample
152 152 query 2; still undecided: 2, sample size is: 2
153 153 2 total queries in *.????s (glob)
154 154 1 changesets found
155 155 list of changesets:
156 156 bec0734cd68e84477ba7fc1d13e6cff53ab70129
157 157 listing keys for "bookmarks"
158 158 bundle2-output-bundle: "HG20", 4 parts total
159 159 bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
160 160 bundle2-output-part: "listkeys" (params: 1 mandatory) empty payload
161 161 bundle2-output-part: "phase-heads" 24 bytes payload
162 162 bundle2-output-part: "cache:rev-branch-cache" streamed payload
163 163 bundle2-input-bundle: with-transaction
164 164 bundle2-input-part: "changegroup" (params: 1 mandatory 1 advisory) supported
165 165 adding changesets
166 166 add changeset bec0734cd68e
167 167 adding manifests
168 168 adding file changes
169 169 adding foo revisions
170 170 added 1 changesets with 1 changes to 1 files (+1 heads)
171 171 bundle2-input-part: total payload size 476
172 172 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
173 173 bundle2-input-part: "phase-heads" supported
174 174 bundle2-input-part: total payload size 24
175 175 bundle2-input-part: "cache:rev-branch-cache" supported
176 176 bundle2-input-part: total payload size 39
177 177 bundle2-input-bundle: 3 parts total
178 178 checking for updated bookmarks
179 179 updating the branch cache
180 180 new changesets bec0734cd68e
181 181 (run 'hg heads' to see heads, 'hg merge' to merge)
@@ -1,1618 +1,1618 b''
1 1 $ cat >> $HGRCPATH << EOF
2 2 > [phases]
3 3 > # public changeset are not obsolete
4 4 > publish=false
5 5 > [ui]
6 6 > logtemplate="{rev}:{node|short} ({phase}{if(obsolete, ' *{obsolete}*')}{if(instabilities, ' {instabilities}')}) [{tags} {bookmarks}] {desc|firstline}{if(obsfate, " [{join(obsfate, "; ")}]")}\n"
7 7 > EOF
8 8 $ mkcommit() {
9 9 > echo "$1" > "$1"
10 10 > hg add "$1"
11 11 > hg ci -m "add $1"
12 12 > }
13 13 $ getid() {
14 14 > hg log -T "{node}\n" --hidden -r "desc('$1')"
15 15 > }
16 16
17 17 $ cat > debugkeys.py <<EOF
18 18 > def reposetup(ui, repo):
19 19 > class debugkeysrepo(repo.__class__):
20 20 > def listkeys(self, namespace):
21 21 > ui.write(b'listkeys %s\n' % (namespace,))
22 22 > return super(debugkeysrepo, self).listkeys(namespace)
23 23 >
24 24 > if repo.local():
25 25 > repo.__class__ = debugkeysrepo
26 26 > EOF
27 27
28 28 $ hg init tmpa
29 29 $ cd tmpa
30 30 $ mkcommit kill_me
31 31
32 32 Checking that the feature is properly disabled
33 33
34 34 $ hg debugobsolete -d '0 0' `getid kill_me` -u babar
35 35 abort: creating obsolete markers is not enabled on this repo
36 36 [255]
37 37
38 38 Enabling it
39 39
40 40 $ cat >> $HGRCPATH << EOF
41 41 > [experimental]
42 42 > evolution=exchange
43 43 > evolution.createmarkers=True
44 44 > EOF
45 45
46 46 Killing a single changeset without replacement
47 47
48 48 $ hg debugobsolete 0
49 49 abort: changeset references must be full hexadecimal node identifiers
50 50 [255]
51 51 $ hg debugobsolete '00'
52 52 abort: changeset references must be full hexadecimal node identifiers
53 53 [255]
54 54 $ hg debugobsolete -d '0 0' `getid kill_me` -u babar
55 55 obsoleted 1 changesets
56 56 $ hg debugobsolete
57 57 97b7c2d76b1845ed3eb988cd612611e72406cef0 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'babar'}
58 58
59 59 (test that mercurial is not confused)
60 60
61 61 $ hg up null --quiet # having 0 as parent prevents it to be hidden
62 62 $ hg tip
63 63 -1:000000000000 (public) [tip ]
64 64 $ hg up --hidden tip --quiet
65 65 updating to a hidden changeset 97b7c2d76b18
66 66 (hidden revision '97b7c2d76b18' is pruned)
67 67
68 68 Killing a single changeset with itself should fail
69 69 (simple local safeguard)
70 70
71 71 $ hg debugobsolete `getid kill_me` `getid kill_me`
72 72 abort: bad obsmarker input: in-marker cycle with 97b7c2d76b1845ed3eb988cd612611e72406cef0
73 73 [255]
74 74
75 75 $ cd ..
76 76
77 77 Killing a single changeset with replacement
78 78 (and testing the format option)
79 79
80 80 $ hg init tmpb
81 81 $ cd tmpb
82 82 $ mkcommit a
83 83 $ mkcommit b
84 84 $ mkcommit original_c
85 85 $ hg up "desc('b')"
86 86 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
87 87 $ mkcommit new_c
88 88 created new head
89 89 $ hg log -r 'hidden()' --template '{rev}:{node|short} {desc}\n' --hidden
90 90 $ hg debugobsolete --config format.obsstore-version=0 --flag 12 `getid original_c` `getid new_c` -d '121 120'
91 91 obsoleted 1 changesets
92 92 $ hg log -r 'hidden()' --template '{rev}:{node|short} {desc}\n' --hidden
93 93 2:245bde4270cd add original_c
94 94 $ hg debugrevlog -cd
95 95 # rev p1rev p2rev start end deltastart base p1 p2 rawsize totalsize compression heads chainlen
96 96 0 -1 -1 0 59 0 0 0 0 58 58 0 1 0
97 97 1 0 -1 59 118 59 59 0 0 58 116 0 1 0
98 98 2 1 -1 118 193 118 118 59 0 76 192 0 1 0
99 99 3 1 -1 193 260 193 193 59 0 66 258 0 2 0
100 100 $ hg debugobsolete
101 101 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
102 102
103 103 (check for version number of the obsstore)
104 104
105 105 $ dd bs=1 count=1 if=.hg/store/obsstore 2>/dev/null
106 106 \x00 (no-eol) (esc)
107 107
108 108 do it again (it read the obsstore before adding new changeset)
109 109
110 110 $ hg up '.^'
111 111 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
112 112 $ mkcommit new_2_c
113 113 created new head
114 114 $ hg debugobsolete -d '1337 0' `getid new_c` `getid new_2_c`
115 115 obsoleted 1 changesets
116 116 $ hg debugobsolete
117 117 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
118 118 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
119 119
120 120 Register two markers with a missing node
121 121
122 122 $ hg up '.^'
123 123 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
124 124 $ mkcommit new_3_c
125 125 created new head
126 126 $ hg debugobsolete -d '1338 0' `getid new_2_c` 1337133713371337133713371337133713371337
127 127 obsoleted 1 changesets
128 128 $ hg debugobsolete -d '1339 0' 1337133713371337133713371337133713371337 `getid new_3_c`
129 129 $ hg debugobsolete
130 130 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
131 131 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
132 132 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
133 133 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
134 134
135 135 Test the --index option of debugobsolete command
136 136 $ hg debugobsolete --index
137 137 0 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
138 138 1 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
139 139 2 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
140 140 3 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
141 141
142 142 Refuse pathological nullid successors
143 143 $ hg debugobsolete -d '9001 0' 1337133713371337133713371337133713371337 0000000000000000000000000000000000000000
144 144 transaction abort!
145 145 rollback completed
146 146 abort: bad obsolescence marker detected: invalid successors nullid
147 147 [255]
148 148
149 149 Check that graphlog detect that a changeset is obsolete:
150 150
151 151 $ hg log -G
152 152 @ 5:5601fb93a350 (draft) [tip ] add new_3_c
153 153 |
154 154 o 1:7c3bad9141dc (draft) [ ] add b
155 155 |
156 156 o 0:1f0dee641bb7 (draft) [ ] add a
157 157
158 158
159 159 check that heads does not report them
160 160
161 161 $ hg heads
162 162 5:5601fb93a350 (draft) [tip ] add new_3_c
163 163 $ hg heads --hidden
164 164 5:5601fb93a350 (draft) [tip ] add new_3_c
165 165 4:ca819180edb9 (draft *obsolete*) [ ] add new_2_c [rewritten as 5:5601fb93a350]
166 166 3:cdbce2fbb163 (draft *obsolete*) [ ] add new_c [rewritten as 4:ca819180edb9]
167 167 2:245bde4270cd (draft *obsolete*) [ ] add original_c [rewritten as 3:cdbce2fbb163]
168 168
169 169
170 170 check that summary does not report them
171 171
172 172 $ hg init ../sink
173 173 $ echo '[paths]' >> .hg/hgrc
174 174 $ echo 'default=../sink' >> .hg/hgrc
175 175 $ hg summary --remote
176 176 parent: 5:5601fb93a350 tip
177 177 add new_3_c
178 178 branch: default
179 179 commit: (clean)
180 180 update: (current)
181 181 phases: 3 draft
182 182 remote: 3 outgoing
183 183
184 184 $ hg summary --remote --hidden
185 185 parent: 5:5601fb93a350 tip
186 186 add new_3_c
187 187 branch: default
188 188 commit: (clean)
189 189 update: 3 new changesets, 4 branch heads (merge)
190 190 phases: 6 draft
191 191 remote: 3 outgoing
192 192
193 193 check that various commands work well with filtering
194 194
195 195 $ hg tip
196 196 5:5601fb93a350 (draft) [tip ] add new_3_c
197 197 $ hg log -r 6
198 198 abort: unknown revision '6'!
199 199 [255]
200 200 $ hg log -r 4
201 201 abort: hidden revision '4' was rewritten as: 5601fb93a350!
202 202 (use --hidden to access hidden revisions)
203 203 [255]
204 204 $ hg debugrevspec 'rev(6)'
205 205 $ hg debugrevspec 'rev(4)'
206 206 $ hg debugrevspec 'null'
207 207 -1
208 208
209 209 Check that public changeset are not accounted as obsolete:
210 210
211 211 $ hg --hidden phase --public 2
212 212 1 new phase-divergent changesets
213 213 $ hg log -G
214 214 @ 5:5601fb93a350 (draft phase-divergent) [tip ] add new_3_c
215 215 |
216 216 | o 2:245bde4270cd (public) [ ] add original_c
217 217 |/
218 218 o 1:7c3bad9141dc (public) [ ] add b
219 219 |
220 220 o 0:1f0dee641bb7 (public) [ ] add a
221 221
222 222
223 223 And that bumped changeset are detected
224 224 --------------------------------------
225 225
226 226 If we didn't filtered obsolete changesets out, 3 and 4 would show up too. Also
227 227 note that the bumped changeset (5:5601fb93a350) is not a direct successor of
228 228 the public changeset
229 229
230 230 $ hg log --hidden -r 'phasedivergent()'
231 231 5:5601fb93a350 (draft phase-divergent) [tip ] add new_3_c
232 232
233 233 And that we can't push bumped changeset
234 234
235 235 $ hg push ../tmpa -r 0 --force #(make repo related)
236 236 pushing to ../tmpa
237 237 searching for changes
238 238 warning: repository is unrelated
239 239 adding changesets
240 240 adding manifests
241 241 adding file changes
242 242 added 1 changesets with 1 changes to 1 files (+1 heads)
243 243 $ hg push ../tmpa
244 244 pushing to ../tmpa
245 245 searching for changes
246 246 abort: push includes phase-divergent changeset: 5601fb93a350!
247 247 [255]
248 248
249 249 Fixing "bumped" situation
250 250 We need to create a clone of 5 and add a special marker with a flag
251 251
252 252 $ hg summary
253 253 parent: 5:5601fb93a350 tip (phase-divergent)
254 254 add new_3_c
255 255 branch: default
256 256 commit: (clean)
257 257 update: 1 new changesets, 2 branch heads (merge)
258 258 phases: 1 draft
259 259 phase-divergent: 1 changesets
260 260 $ hg up '5^'
261 261 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
262 262 $ hg revert -ar 5
263 263 adding new_3_c
264 264 $ hg ci -m 'add n3w_3_c'
265 265 created new head
266 266 $ hg debugobsolete -d '1338 0' --flags 1 `getid new_3_c` `getid n3w_3_c`
267 267 obsoleted 1 changesets
268 268 $ hg log -r 'phasedivergent()'
269 269 $ hg log -G
270 270 @ 6:6f9641995072 (draft) [tip ] add n3w_3_c
271 271 |
272 272 | o 2:245bde4270cd (public) [ ] add original_c
273 273 |/
274 274 o 1:7c3bad9141dc (public) [ ] add b
275 275 |
276 276 o 0:1f0dee641bb7 (public) [ ] add a
277 277
278 278
279 279 Basic exclusive testing
280 280
281 281 $ hg log -G --hidden
282 282 @ 6:6f9641995072 (draft) [tip ] add n3w_3_c
283 283 |
284 284 | x 5:5601fb93a350 (draft *obsolete*) [ ] add new_3_c [rewritten as 6:6f9641995072]
285 285 |/
286 286 | x 4:ca819180edb9 (draft *obsolete*) [ ] add new_2_c [rewritten as 5:5601fb93a350]
287 287 |/
288 288 | x 3:cdbce2fbb163 (draft *obsolete*) [ ] add new_c [rewritten as 4:ca819180edb9]
289 289 |/
290 290 | o 2:245bde4270cd (public) [ ] add original_c
291 291 |/
292 292 o 1:7c3bad9141dc (public) [ ] add b
293 293 |
294 294 o 0:1f0dee641bb7 (public) [ ] add a
295 295
296 296 $ hg debugobsolete --rev 6f9641995072
297 297 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
298 298 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
299 299 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
300 300 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
301 301 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
302 302 $ hg debugobsolete --rev 6f9641995072 --exclusive
303 303 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
304 304 $ hg debugobsolete --rev 5601fb93a350 --hidden
305 305 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
306 306 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
307 307 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
308 308 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
309 309 $ hg debugobsolete --rev 5601fb93a350 --hidden --exclusive
310 310 $ hg debugobsolete --rev 5601fb93a350+6f9641995072 --hidden --exclusive
311 311 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
312 312 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
313 313 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
314 314
315 315 $ cd ..
316 316
317 317 Revision 0 is hidden
318 318 --------------------
319 319
320 320 $ hg init rev0hidden
321 321 $ cd rev0hidden
322 322
323 323 $ mkcommit kill0
324 324 $ hg up -q null
325 325 $ hg debugobsolete `getid kill0`
326 326 obsoleted 1 changesets
327 327 $ mkcommit a
328 328 $ mkcommit b
329 329
330 330 Should pick the first visible revision as "repo" node
331 331
332 332 $ hg archive ../archive-null
333 333 $ cat ../archive-null/.hg_archival.txt
334 334 repo: 1f0dee641bb7258c56bd60e93edfa2405381c41e
335 335 node: 7c3bad9141dcb46ff89abf5f61856facd56e476c
336 336 branch: default
337 337 latesttag: null
338 338 latesttagdistance: 2
339 339 changessincelatesttag: 2
340 340
341 341
342 342 $ cd ..
343 343
344 344 Can disable transaction summary report
345 345
346 346 $ hg init transaction-summary
347 347 $ cd transaction-summary
348 348 $ mkcommit a
349 349 $ mkcommit b
350 350 $ hg up -q null
351 351 $ hg --config experimental.evolution.report-instabilities=false debugobsolete `getid a`
352 352 obsoleted 1 changesets
353 353 $ cd ..
354 354
355 355 Exchange Test
356 356 ============================
357 357
358 358 Destination repo does not have any data
359 359 ---------------------------------------
360 360
361 361 Simple incoming test
362 362
363 363 $ hg init tmpc
364 364 $ cd tmpc
365 365 $ hg incoming ../tmpb
366 366 comparing with ../tmpb
367 367 0:1f0dee641bb7 (public) [ ] add a
368 368 1:7c3bad9141dc (public) [ ] add b
369 369 2:245bde4270cd (public) [ ] add original_c
370 370 6:6f9641995072 (draft) [tip ] add n3w_3_c
371 371
372 372 Try to pull markers
373 373 (extinct changeset are excluded but marker are pushed)
374 374
375 375 $ hg pull ../tmpb
376 376 pulling from ../tmpb
377 377 requesting all changes
378 378 adding changesets
379 379 adding manifests
380 380 adding file changes
381 381 added 4 changesets with 4 changes to 4 files (+1 heads)
382 382 5 new obsolescence markers
383 383 new changesets 1f0dee641bb7:6f9641995072
384 384 (run 'hg heads' to see heads, 'hg merge' to merge)
385 385 $ hg debugobsolete
386 386 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
387 387 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
388 388 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
389 389 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
390 390 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
391 391
392 392 Rollback//Transaction support
393 393
394 394 $ hg debugobsolete -d '1340 0' aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
395 395 $ hg debugobsolete
396 396 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
397 397 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
398 398 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
399 399 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
400 400 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
401 401 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 0 (Thu Jan 01 00:22:20 1970 +0000) {'user': 'test'}
402 402 $ hg rollback -n
403 403 repository tip rolled back to revision 3 (undo debugobsolete)
404 404 $ hg rollback
405 405 repository tip rolled back to revision 3 (undo debugobsolete)
406 406 $ hg debugobsolete
407 407 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
408 408 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
409 409 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
410 410 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
411 411 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
412 412
413 413 $ cd ..
414 414
415 415 Try to push markers
416 416
417 417 $ hg init tmpd
418 418 $ hg -R tmpb push tmpd
419 419 pushing to tmpd
420 420 searching for changes
421 421 adding changesets
422 422 adding manifests
423 423 adding file changes
424 424 added 4 changesets with 4 changes to 4 files (+1 heads)
425 425 5 new obsolescence markers
426 426 $ hg -R tmpd debugobsolete | sort
427 427 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
428 428 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
429 429 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
430 430 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
431 431 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
432 432
433 433 Check obsolete keys are exchanged only if source has an obsolete store
434 434
435 435 $ hg init empty
436 436 $ hg --config extensions.debugkeys=debugkeys.py -R empty push tmpd
437 437 pushing to tmpd
438 438 listkeys phases
439 439 listkeys bookmarks
440 440 no changes found
441 441 listkeys phases
442 442 [1]
443 443
444 444 clone support
445 445 (markers are copied and extinct changesets are included to allow hardlinks)
446 446
447 447 $ hg clone tmpb clone-dest
448 448 updating to branch default
449 449 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
450 450 $ hg -R clone-dest log -G --hidden
451 451 @ 6:6f9641995072 (draft) [tip ] add n3w_3_c
452 452 |
453 453 | x 5:5601fb93a350 (draft *obsolete*) [ ] add new_3_c [rewritten as 6:6f9641995072]
454 454 |/
455 455 | x 4:ca819180edb9 (draft *obsolete*) [ ] add new_2_c [rewritten as 5:5601fb93a350]
456 456 |/
457 457 | x 3:cdbce2fbb163 (draft *obsolete*) [ ] add new_c [rewritten as 4:ca819180edb9]
458 458 |/
459 459 | o 2:245bde4270cd (public) [ ] add original_c
460 460 |/
461 461 o 1:7c3bad9141dc (public) [ ] add b
462 462 |
463 463 o 0:1f0dee641bb7 (public) [ ] add a
464 464
465 465 $ hg -R clone-dest debugobsolete
466 466 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
467 467 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
468 468 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
469 469 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
470 470 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
471 471
472 472
473 473 Destination repo have existing data
474 474 ---------------------------------------
475 475
476 476 On pull
477 477
478 478 $ hg init tmpe
479 479 $ cd tmpe
480 480 $ hg debugobsolete -d '1339 0' 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00
481 481 $ hg pull ../tmpb
482 482 pulling from ../tmpb
483 483 requesting all changes
484 484 adding changesets
485 485 adding manifests
486 486 adding file changes
487 487 added 4 changesets with 4 changes to 4 files (+1 heads)
488 488 5 new obsolescence markers
489 489 new changesets 1f0dee641bb7:6f9641995072
490 490 (run 'hg heads' to see heads, 'hg merge' to merge)
491 491 $ hg debugobsolete
492 492 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
493 493 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
494 494 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
495 495 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
496 496 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
497 497 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
498 498
499 499
500 500 On push
501 501
502 502 $ hg push ../tmpc
503 503 pushing to ../tmpc
504 504 searching for changes
505 505 no changes found
506 506 1 new obsolescence markers
507 507 [1]
508 508 $ hg -R ../tmpc debugobsolete
509 509 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
510 510 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
511 511 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
512 512 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
513 513 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
514 514 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
515 515
516 516 detect outgoing obsolete and unstable
517 517 ---------------------------------------
518 518
519 519
520 520 $ hg log -G
521 521 o 3:6f9641995072 (draft) [tip ] add n3w_3_c
522 522 |
523 523 | o 2:245bde4270cd (public) [ ] add original_c
524 524 |/
525 525 o 1:7c3bad9141dc (public) [ ] add b
526 526 |
527 527 o 0:1f0dee641bb7 (public) [ ] add a
528 528
529 529 $ hg up 'desc("n3w_3_c")'
530 530 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
531 531 $ mkcommit original_d
532 532 $ mkcommit original_e
533 533 $ hg debugobsolete --record-parents `getid original_d` -d '0 0'
534 534 obsoleted 1 changesets
535 535 1 new orphan changesets
536 536 $ hg debugobsolete | grep `getid original_d`
537 537 94b33453f93bdb8d457ef9b770851a618bf413e1 0 {6f96419950729f3671185b847352890f074f7557} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
538 538 $ hg log -r 'obsolete()'
539 539 4:94b33453f93b (draft *obsolete*) [ ] add original_d [pruned]
540 540 $ hg summary
541 541 parent: 5:cda648ca50f5 tip (orphan)
542 542 add original_e
543 543 branch: default
544 544 commit: (clean)
545 545 update: 1 new changesets, 2 branch heads (merge)
546 546 phases: 3 draft
547 547 orphan: 1 changesets
548 548 $ hg log -G -r '::orphan()'
549 549 @ 5:cda648ca50f5 (draft orphan) [tip ] add original_e
550 550 |
551 551 x 4:94b33453f93b (draft *obsolete*) [ ] add original_d [pruned]
552 552 |
553 553 o 3:6f9641995072 (draft) [ ] add n3w_3_c
554 554 |
555 555 o 1:7c3bad9141dc (public) [ ] add b
556 556 |
557 557 o 0:1f0dee641bb7 (public) [ ] add a
558 558
559 559
560 560 refuse to push obsolete changeset
561 561
562 562 $ hg push ../tmpc/ -r 'desc("original_d")'
563 563 pushing to ../tmpc/
564 564 searching for changes
565 565 abort: push includes obsolete changeset: 94b33453f93b!
566 566 [255]
567 567
568 568 refuse to push unstable changeset
569 569
570 570 $ hg push ../tmpc/
571 571 pushing to ../tmpc/
572 572 searching for changes
573 573 abort: push includes orphan changeset: cda648ca50f5!
574 574 [255]
575 575
576 576 Test that extinct changeset are properly detected
577 577
578 578 $ hg log -r 'extinct()'
579 579
580 580 Don't try to push extinct changeset
581 581
582 582 $ hg init ../tmpf
583 583 $ hg out ../tmpf
584 584 comparing with ../tmpf
585 585 searching for changes
586 586 0:1f0dee641bb7 (public) [ ] add a
587 587 1:7c3bad9141dc (public) [ ] add b
588 588 2:245bde4270cd (public) [ ] add original_c
589 589 3:6f9641995072 (draft) [ ] add n3w_3_c
590 590 4:94b33453f93b (draft *obsolete*) [ ] add original_d [pruned]
591 591 5:cda648ca50f5 (draft orphan) [tip ] add original_e
592 592 $ hg push ../tmpf -f # -f because be push unstable too
593 593 pushing to ../tmpf
594 594 searching for changes
595 595 adding changesets
596 596 adding manifests
597 597 adding file changes
598 598 added 6 changesets with 6 changes to 6 files (+1 heads)
599 599 7 new obsolescence markers
600 600 1 new orphan changesets
601 601
602 602 no warning displayed
603 603
604 604 $ hg push ../tmpf
605 605 pushing to ../tmpf
606 606 searching for changes
607 607 no changes found
608 608 [1]
609 609
610 610 Do not warn about new head when the new head is a successors of a remote one
611 611
612 612 $ hg log -G
613 613 @ 5:cda648ca50f5 (draft orphan) [tip ] add original_e
614 614 |
615 615 x 4:94b33453f93b (draft *obsolete*) [ ] add original_d [pruned]
616 616 |
617 617 o 3:6f9641995072 (draft) [ ] add n3w_3_c
618 618 |
619 619 | o 2:245bde4270cd (public) [ ] add original_c
620 620 |/
621 621 o 1:7c3bad9141dc (public) [ ] add b
622 622 |
623 623 o 0:1f0dee641bb7 (public) [ ] add a
624 624
625 625 $ hg up -q 'desc(n3w_3_c)'
626 626 $ mkcommit obsolete_e
627 627 created new head
628 628 $ hg debugobsolete `getid 'original_e'` `getid 'obsolete_e'` \
629 629 > -u 'test <test@example.net>'
630 630 obsoleted 1 changesets
631 631 $ hg outgoing ../tmpf # parasite hg outgoing testin
632 632 comparing with ../tmpf
633 633 searching for changes
634 634 6:3de5eca88c00 (draft) [tip ] add obsolete_e
635 635 $ hg push ../tmpf
636 636 pushing to ../tmpf
637 637 searching for changes
638 638 adding changesets
639 639 adding manifests
640 640 adding file changes
641 641 added 1 changesets with 1 changes to 1 files (+1 heads)
642 642 1 new obsolescence markers
643 643 obsoleted 1 changesets
644 644
645 645 test relevance computation
646 646 ---------------------------------------
647 647
648 648 Checking simple case of "marker relevance".
649 649
650 650
651 651 Reminder of the repo situation
652 652
653 653 $ hg log --hidden --graph
654 654 @ 6:3de5eca88c00 (draft) [tip ] add obsolete_e
655 655 |
656 656 | x 5:cda648ca50f5 (draft *obsolete*) [ ] add original_e [rewritten as 6:3de5eca88c00 by test <test@example.net>]
657 657 | |
658 658 | x 4:94b33453f93b (draft *obsolete*) [ ] add original_d [pruned]
659 659 |/
660 660 o 3:6f9641995072 (draft) [ ] add n3w_3_c
661 661 |
662 662 | o 2:245bde4270cd (public) [ ] add original_c
663 663 |/
664 664 o 1:7c3bad9141dc (public) [ ] add b
665 665 |
666 666 o 0:1f0dee641bb7 (public) [ ] add a
667 667
668 668
669 669 List of all markers
670 670
671 671 $ hg debugobsolete
672 672 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
673 673 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
674 674 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
675 675 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
676 676 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
677 677 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
678 678 94b33453f93bdb8d457ef9b770851a618bf413e1 0 {6f96419950729f3671185b847352890f074f7557} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
679 679 cda648ca50f50482b7055c0b0c4c117bba6733d9 3de5eca88c00aa039da7399a220f4a5221faa585 0 (*) {'user': 'test <test@example.net>'} (glob)
680 680
681 681 List of changesets with no chain
682 682
683 683 $ hg debugobsolete --hidden --rev ::2
684 684
685 685 List of changesets that are included on marker chain
686 686
687 687 $ hg debugobsolete --hidden --rev 6
688 688 cda648ca50f50482b7055c0b0c4c117bba6733d9 3de5eca88c00aa039da7399a220f4a5221faa585 0 (*) {'user': 'test <test@example.net>'} (glob)
689 689
690 690 List of changesets with a longer chain, (including a pruned children)
691 691
692 692 $ hg debugobsolete --hidden --rev 3
693 693 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
694 694 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
695 695 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
696 696 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
697 697 94b33453f93bdb8d457ef9b770851a618bf413e1 0 {6f96419950729f3671185b847352890f074f7557} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
698 698 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
699 699 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
700 700
701 701 List of both
702 702
703 703 $ hg debugobsolete --hidden --rev 3::6
704 704 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
705 705 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
706 706 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
707 707 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
708 708 94b33453f93bdb8d457ef9b770851a618bf413e1 0 {6f96419950729f3671185b847352890f074f7557} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
709 709 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
710 710 cda648ca50f50482b7055c0b0c4c117bba6733d9 3de5eca88c00aa039da7399a220f4a5221faa585 0 (*) {'user': 'test <test@example.net>'} (glob)
711 711 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
712 712
713 713 List of all markers in JSON
714 714
715 715 $ hg debugobsolete -Tjson
716 716 [
717 717 {
718 718 "date": [1339, 0],
719 719 "flag": 0,
720 720 "metadata": {"user": "test"},
721 721 "prednode": "1339133913391339133913391339133913391339",
722 722 "succnodes": ["ca819180edb99ed25ceafb3e9584ac287e240b00"]
723 723 },
724 724 {
725 725 "date": [1339, 0],
726 726 "flag": 0,
727 727 "metadata": {"user": "test"},
728 728 "prednode": "1337133713371337133713371337133713371337",
729 729 "succnodes": ["5601fb93a350734d935195fee37f4054c529ff39"]
730 730 },
731 731 {
732 732 "date": [121, 120],
733 733 "flag": 12,
734 734 "metadata": {"user": "test"},
735 735 "prednode": "245bde4270cd1072a27757984f9cda8ba26f08ca",
736 736 "succnodes": ["cdbce2fbb16313928851e97e0d85413f3f7eb77f"]
737 737 },
738 738 {
739 739 "date": [1338, 0],
740 740 "flag": 1,
741 741 "metadata": {"user": "test"},
742 742 "prednode": "5601fb93a350734d935195fee37f4054c529ff39",
743 743 "succnodes": ["6f96419950729f3671185b847352890f074f7557"]
744 744 },
745 745 {
746 746 "date": [1338, 0],
747 747 "flag": 0,
748 748 "metadata": {"user": "test"},
749 749 "prednode": "ca819180edb99ed25ceafb3e9584ac287e240b00",
750 750 "succnodes": ["1337133713371337133713371337133713371337"]
751 751 },
752 752 {
753 753 "date": [1337, 0],
754 754 "flag": 0,
755 755 "metadata": {"user": "test"},
756 756 "prednode": "cdbce2fbb16313928851e97e0d85413f3f7eb77f",
757 757 "succnodes": ["ca819180edb99ed25ceafb3e9584ac287e240b00"]
758 758 },
759 759 {
760 760 "date": [0, 0],
761 761 "flag": 0,
762 762 "metadata": {"user": "test"},
763 763 "parentnodes": ["6f96419950729f3671185b847352890f074f7557"],
764 764 "prednode": "94b33453f93bdb8d457ef9b770851a618bf413e1",
765 765 "succnodes": []
766 766 },
767 767 {
768 768 "date": *, (glob)
769 769 "flag": 0,
770 770 "metadata": {"user": "test <test@example.net>"},
771 771 "prednode": "cda648ca50f50482b7055c0b0c4c117bba6733d9",
772 772 "succnodes": ["3de5eca88c00aa039da7399a220f4a5221faa585"]
773 773 }
774 774 ]
775 775
776 776 Template keywords
777 777
778 778 $ hg debugobsolete -r6 -T '{succnodes % "{node|short}"} {date|shortdate}\n'
779 779 3de5eca88c00 ????-??-?? (glob)
780 780 $ hg debugobsolete -r6 -T '{join(metadata % "{key}={value}", " ")}\n'
781 781 user=test <test@example.net>
782 782 $ hg debugobsolete -r6 -T '{metadata}\n{metadata}\n'
783 783 'user': 'test <test@example.net>'
784 784 'user': 'test <test@example.net>'
785 785 $ hg debugobsolete -r6 -T '{succnodes}\n{succnodes}\n'
786 786 3de5eca88c00aa039da7399a220f4a5221faa585
787 787 3de5eca88c00aa039da7399a220f4a5221faa585
788 788 $ hg debugobsolete -r6 -T '{flag} {get(metadata, "user")}\n'
789 789 0 test <test@example.net>
790 790
791 791 Test the debug output for exchange
792 792 ----------------------------------
793 793
794 794 $ hg pull ../tmpb --config 'experimental.obsmarkers-exchange-debug=True' # bundle2
795 795 pulling from ../tmpb
796 796 searching for changes
797 797 no changes found
798 798 obsmarker-exchange: 346 bytes received
799 799
800 800 check hgweb does not explode
801 801 ====================================
802 802
803 803 $ hg unbundle $TESTDIR/bundles/hgweb+obs.hg
804 804 adding changesets
805 805 adding manifests
806 806 adding file changes
807 807 added 62 changesets with 63 changes to 9 files (+60 heads)
808 808 new changesets 50c51b361e60:c15e9edfca13
809 809 (run 'hg heads .' to see heads, 'hg merge' to merge)
810 810 $ for node in `hg log -r 'desc(babar_)' --template '{node}\n'`;
811 811 > do
812 812 > hg debugobsolete $node
813 813 > done
814 814 obsoleted 1 changesets
815 815 obsoleted 1 changesets
816 816 obsoleted 1 changesets
817 817 obsoleted 1 changesets
818 818 obsoleted 1 changesets
819 819 obsoleted 1 changesets
820 820 obsoleted 1 changesets
821 821 obsoleted 1 changesets
822 822 obsoleted 1 changesets
823 823 obsoleted 1 changesets
824 824 obsoleted 1 changesets
825 825 obsoleted 1 changesets
826 826 obsoleted 1 changesets
827 827 obsoleted 1 changesets
828 828 obsoleted 1 changesets
829 829 obsoleted 1 changesets
830 830 obsoleted 1 changesets
831 831 obsoleted 1 changesets
832 832 obsoleted 1 changesets
833 833 obsoleted 1 changesets
834 834 obsoleted 1 changesets
835 835 obsoleted 1 changesets
836 836 obsoleted 1 changesets
837 837 obsoleted 1 changesets
838 838 obsoleted 1 changesets
839 839 obsoleted 1 changesets
840 840 obsoleted 1 changesets
841 841 obsoleted 1 changesets
842 842 obsoleted 1 changesets
843 843 obsoleted 1 changesets
844 844 obsoleted 1 changesets
845 845 obsoleted 1 changesets
846 846 obsoleted 1 changesets
847 847 obsoleted 1 changesets
848 848 obsoleted 1 changesets
849 849 obsoleted 1 changesets
850 850 obsoleted 1 changesets
851 851 obsoleted 1 changesets
852 852 obsoleted 1 changesets
853 853 obsoleted 1 changesets
854 854 obsoleted 1 changesets
855 855 obsoleted 1 changesets
856 856 obsoleted 1 changesets
857 857 obsoleted 1 changesets
858 858 obsoleted 1 changesets
859 859 obsoleted 1 changesets
860 860 obsoleted 1 changesets
861 861 obsoleted 1 changesets
862 862 obsoleted 1 changesets
863 863 obsoleted 1 changesets
864 864 obsoleted 1 changesets
865 865 obsoleted 1 changesets
866 866 obsoleted 1 changesets
867 867 obsoleted 1 changesets
868 868 obsoleted 1 changesets
869 869 obsoleted 1 changesets
870 870 obsoleted 1 changesets
871 871 obsoleted 1 changesets
872 872 obsoleted 1 changesets
873 873 obsoleted 1 changesets
874 874 $ hg up tip
875 875 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
876 876
877 877 #if serve
878 878
879 879 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
880 880 $ cat hg.pid >> $DAEMON_PIDS
881 881
882 882 check changelog view
883 883
884 884 $ get-with-headers.py --headeronly localhost:$HGPORT 'shortlog/'
885 885 200 Script output follows
886 886
887 887 check graph view
888 888
889 889 $ get-with-headers.py --headeronly localhost:$HGPORT 'graph'
890 890 200 Script output follows
891 891
892 892 check filelog view
893 893
894 894 $ get-with-headers.py --headeronly localhost:$HGPORT 'log/'`hg log -r . -T "{node}"`/'babar'
895 895 200 Script output follows
896 896
897 897 check filelog view for hidden commits (obsolete ones are hidden here)
898 898
899 899 $ get-with-headers.py localhost:$HGPORT 'log/'`hg log -r . -T "{node}"`/'babar' | grep obsolete
900 900 [1]
901 901
902 902 $ get-with-headers.py --headeronly localhost:$HGPORT 'rev/68'
903 903 200 Script output follows
904 904 $ get-with-headers.py --headeronly localhost:$HGPORT 'rev/67'
905 905 404 Not Found
906 906 [1]
907 907
908 908 check that web.view config option:
909 909
910 910 $ killdaemons.py hg.pid
911 911 $ cat >> .hg/hgrc << EOF
912 912 > [web]
913 913 > view=all
914 914 > EOF
915 915 $ wait
916 916 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
917 917 $ get-with-headers.py --headeronly localhost:$HGPORT 'rev/67'
918 918 200 Script output follows
919 919 $ killdaemons.py hg.pid
920 920
921 921 Checking _enable=False warning if obsolete marker exists
922 922
923 923 $ echo '[experimental]' >> $HGRCPATH
924 924 $ echo "evolution=" >> $HGRCPATH
925 925 $ hg log -r tip
926 926 68:c15e9edfca13 (draft) [tip ] add celestine
927 927
928 928 reenable for later test
929 929
930 930 $ echo '[experimental]' >> $HGRCPATH
931 931 $ echo "evolution.exchange=True" >> $HGRCPATH
932 932 $ echo "evolution.createmarkers=True" >> $HGRCPATH
933 933
934 934 $ rm hg.pid access.log errors.log
935 935 #endif
936 936
937 937 Several troubles on the same changeset (create an unstable and bumped changeset)
938 938
939 939 $ hg debugobsolete `getid obsolete_e`
940 940 obsoleted 1 changesets
941 941 2 new orphan changesets
942 942 $ hg debugobsolete `getid original_c` `getid babar`
943 943 1 new phase-divergent changesets
944 944 $ hg log --config ui.logtemplate= -r 'phasedivergent() and orphan()'
945 945 changeset: 7:50c51b361e60
946 946 user: test
947 947 date: Thu Jan 01 00:00:00 1970 +0000
948 948 instability: orphan, phase-divergent
949 949 summary: add babar
950 950
951 951
952 952 test the "obsolete" templatekw
953 953
954 954 $ hg log -r 'obsolete()'
955 955 6:3de5eca88c00 (draft *obsolete*) [ ] add obsolete_e [pruned]
956 956
957 957 test the "troubles" templatekw
958 958
959 959 $ hg log -r 'phasedivergent() and orphan()'
960 960 7:50c51b361e60 (draft orphan phase-divergent) [ ] add babar
961 961
962 962 test the default cmdline template
963 963
964 964 $ hg log -T default -r 'phasedivergent()'
965 965 changeset: 7:50c51b361e60
966 966 user: test
967 967 date: Thu Jan 01 00:00:00 1970 +0000
968 968 instability: orphan, phase-divergent
969 969 summary: add babar
970 970
971 971 $ hg log -T default -r 'obsolete()'
972 972 changeset: 6:3de5eca88c00
973 973 parent: 3:6f9641995072
974 974 user: test
975 975 date: Thu Jan 01 00:00:00 1970 +0000
976 976 obsolete: pruned
977 977 summary: add obsolete_e
978 978
979 979
980 980 test the obsolete labels
981 981
982 982 $ hg log --config ui.logtemplate= --color=debug -r 'phasedivergent()'
983 983 [log.changeset changeset.draft changeset.unstable instability.orphan instability.phase-divergent|changeset: 7:50c51b361e60]
984 984 [log.user|user: test]
985 985 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
986 986 [log.instability|instability: orphan, phase-divergent]
987 987 [log.summary|summary: add babar]
988 988
989 989
990 990 $ hg log -T default -r 'phasedivergent()' --color=debug
991 991 [log.changeset changeset.draft changeset.unstable instability.orphan instability.phase-divergent|changeset: 7:50c51b361e60]
992 992 [log.user|user: test]
993 993 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
994 994 [log.instability|instability: orphan, phase-divergent]
995 995 [log.summary|summary: add babar]
996 996
997 997
998 998 $ hg log --config ui.logtemplate= --color=debug -r "obsolete()"
999 999 [log.changeset changeset.draft changeset.obsolete|changeset: 6:3de5eca88c00]
1000 1000 [log.parent changeset.draft|parent: 3:6f9641995072]
1001 1001 [log.user|user: test]
1002 1002 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
1003 1003 [log.obsfate|obsolete: pruned]
1004 1004 [log.summary|summary: add obsolete_e]
1005 1005
1006 1006
1007 1007 $ hg log -T default -r 'obsolete()' --color=debug
1008 1008 [log.changeset changeset.draft changeset.obsolete|changeset: 6:3de5eca88c00]
1009 1009 [log.parent changeset.draft|parent: 3:6f9641995072]
1010 1010 [log.user|user: test]
1011 1011 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
1012 1012 [log.obsfate|obsolete: pruned]
1013 1013 [log.summary|summary: add obsolete_e]
1014 1014
1015 1015
1016 1016 test summary output
1017 1017
1018 1018 $ hg up -r 'phasedivergent() and orphan()'
1019 1019 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1020 1020 $ hg summary
1021 1021 parent: 7:50c51b361e60 (orphan, phase-divergent)
1022 1022 add babar
1023 1023 branch: default
1024 1024 commit: (clean)
1025 1025 update: 2 new changesets (update)
1026 1026 phases: 4 draft
1027 1027 orphan: 2 changesets
1028 1028 phase-divergent: 1 changesets
1029 1029 $ hg up -r 'obsolete()'
1030 1030 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1031 1031 $ hg summary
1032 1032 parent: 6:3de5eca88c00 (obsolete)
1033 1033 add obsolete_e
1034 1034 branch: default
1035 1035 commit: (clean)
1036 1036 update: 3 new changesets (update)
1037 1037 phases: 4 draft
1038 1038 orphan: 2 changesets
1039 1039 phase-divergent: 1 changesets
1040 1040
1041 1041 test debugwhyunstable output
1042 1042
1043 1043 $ hg debugwhyunstable 50c51b361e60
1044 1044 orphan: obsolete parent 3de5eca88c00aa039da7399a220f4a5221faa585
1045 1045 phase-divergent: immutable predecessor 245bde4270cd1072a27757984f9cda8ba26f08ca
1046 1046
1047 1047 test whyunstable template keyword
1048 1048
1049 1049 $ hg log -r 50c51b361e60 -T '{whyunstable}\n'
1050 1050 orphan: obsolete parent 3de5eca88c00
1051 1051 phase-divergent: immutable predecessor 245bde4270cd
1052 1052 $ hg log -r 50c51b361e60 -T '{whyunstable % "{instability}: {reason} {node|shortest}\n"}'
1053 1053 orphan: obsolete parent 3de5
1054 1054 phase-divergent: immutable predecessor 245b
1055 1055
1056 1056 #if serve
1057 1057
1058 1058 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
1059 1059 $ cat hg.pid >> $DAEMON_PIDS
1060 1060
1061 1061 check obsolete changeset
1062 1062
1063 1063 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(obsolete())&style=paper' | grep '<span class="obsolete">'
1064 1064 <span class="phase">draft</span> <span class="obsolete">obsolete</span>
1065 1065 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(obsolete())&style=coal' | grep '<span class="obsolete">'
1066 1066 <span class="phase">draft</span> <span class="obsolete">obsolete</span>
1067 1067 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(obsolete())&style=gitweb' | grep '<span class="logtags">'
1068 1068 <span class="logtags"><span class="phasetag" title="draft">draft</span> <span class="obsoletetag" title="obsolete">obsolete</span> </span>
1069 1069 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(obsolete())&style=monoblue' | grep '<span class="logtags">'
1070 1070 <span class="logtags"><span class="phasetag" title="draft">draft</span> <span class="obsoletetag" title="obsolete">obsolete</span> </span>
1071 1071 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(obsolete())&style=spartan' | grep 'class="obsolete"'
1072 1072 <th class="obsolete">obsolete:</th>
1073 1073 <td class="obsolete">pruned by &#116;&#101;&#115;&#116; <span class="age">Thu, 01 Jan 1970 00:00:00 +0000</span></td>
1074 1074
1075 1075 check changeset with instabilities
1076 1076
1077 1077 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(phasedivergent())&style=paper' | grep '<span class="instability">'
1078 1078 <span class="phase">draft</span> <span class="instability">orphan</span> <span class="instability">phase-divergent</span>
1079 1079 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(phasedivergent())&style=coal' | grep '<span class="instability">'
1080 1080 <span class="phase">draft</span> <span class="instability">orphan</span> <span class="instability">phase-divergent</span>
1081 1081 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(phasedivergent())&style=gitweb' | grep '<span class="logtags">'
1082 1082 <span class="logtags"><span class="phasetag" title="draft">draft</span> <span class="instabilitytag" title="orphan">orphan</span> <span class="instabilitytag" title="phase-divergent">phase-divergent</span> </span>
1083 1083 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(phasedivergent())&style=monoblue' | grep '<span class="logtags">'
1084 1084 <span class="logtags"><span class="phasetag" title="draft">draft</span> <span class="instabilitytag" title="orphan">orphan</span> <span class="instabilitytag" title="phase-divergent">phase-divergent</span> </span>
1085 1085 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(phasedivergent())&style=spartan' | grep 'class="unstable"'
1086 1086 <th class="unstable">unstable:</th>
1087 1087 <td class="unstable">orphan: obsolete parent <a href="/rev/3de5eca88c00?style=spartan">3de5eca88c00</a></td>
1088 1088 <th class="unstable">unstable:</th>
1089 1089 <td class="unstable">phase-divergent: immutable predecessor <a href="/rev/245bde4270cd?style=spartan">245bde4270cd</a></td>
1090 1090
1091 1091 check explanation for an orphan and phase-divergent changeset
1092 1092
1093 1093 $ get-with-headers.py localhost:$HGPORT 'rev/50c51b361e60?style=paper' | egrep '(orphan|phase-divergent):'
1094 1094 <td>orphan: obsolete parent <a href="/rev/3de5eca88c00?style=paper">3de5eca88c00</a><br>
1095 1095 phase-divergent: immutable predecessor <a href="/rev/245bde4270cd?style=paper">245bde4270cd</a></td>
1096 1096 $ get-with-headers.py localhost:$HGPORT 'rev/50c51b361e60?style=coal' | egrep '(orphan|phase-divergent):'
1097 1097 <td>orphan: obsolete parent <a href="/rev/3de5eca88c00?style=coal">3de5eca88c00</a><br>
1098 1098 phase-divergent: immutable predecessor <a href="/rev/245bde4270cd?style=coal">245bde4270cd</a></td>
1099 1099 $ get-with-headers.py localhost:$HGPORT 'rev/50c51b361e60?style=gitweb' | egrep '(orphan|phase-divergent):'
1100 1100 <td>orphan: obsolete parent <a class="list" href="/rev/3de5eca88c00?style=gitweb">3de5eca88c00</a></td>
1101 1101 <td>phase-divergent: immutable predecessor <a class="list" href="/rev/245bde4270cd?style=gitweb">245bde4270cd</a></td>
1102 1102 $ get-with-headers.py localhost:$HGPORT 'rev/50c51b361e60?style=monoblue' | egrep '(orphan|phase-divergent):'
1103 1103 <dd>orphan: obsolete parent <a href="/rev/3de5eca88c00?style=monoblue">3de5eca88c00</a></dd>
1104 1104 <dd>phase-divergent: immutable predecessor <a href="/rev/245bde4270cd?style=monoblue">245bde4270cd</a></dd>
1105 1105 $ get-with-headers.py localhost:$HGPORT 'rev/50c51b361e60?style=spartan' | egrep '(orphan|phase-divergent):'
1106 1106 <td class="unstable">orphan: obsolete parent <a href="/rev/3de5eca88c00?style=spartan">3de5eca88c00</a></td>
1107 1107 <td class="unstable">phase-divergent: immutable predecessor <a href="/rev/245bde4270cd?style=spartan">245bde4270cd</a></td>
1108 1108
1109 1109 $ killdaemons.py
1110 1110
1111 1111 $ rm hg.pid access.log errors.log
1112 1112
1113 1113 #endif
1114 1114
1115 1115 Test incoming/outcoming with changesets obsoleted remotely, known locally
1116 1116 ===============================================================================
1117 1117
1118 1118 This test issue 3805
1119 1119
1120 1120 $ hg init repo-issue3805
1121 1121 $ cd repo-issue3805
1122 1122 $ echo "base" > base
1123 1123 $ hg ci -Am "base"
1124 1124 adding base
1125 1125 $ echo "foo" > foo
1126 1126 $ hg ci -Am "A"
1127 1127 adding foo
1128 1128 $ hg clone . ../other-issue3805
1129 1129 updating to branch default
1130 1130 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1131 1131 $ echo "bar" >> foo
1132 1132 $ hg ci --amend
1133 1133 $ cd ../other-issue3805
1134 1134 $ hg log -G
1135 1135 @ 1:29f0c6921ddd (draft) [tip ] A
1136 1136 |
1137 1137 o 0:d20a80d4def3 (draft) [ ] base
1138 1138
1139 1139 $ hg log -G -R ../repo-issue3805
1140 1140 @ 2:323a9c3ddd91 (draft) [tip ] A
1141 1141 |
1142 1142 o 0:d20a80d4def3 (draft) [ ] base
1143 1143
1144 1144 $ hg incoming
1145 1145 comparing with $TESTTMP/tmpe/repo-issue3805
1146 1146 searching for changes
1147 1147 2:323a9c3ddd91 (draft) [tip ] A
1148 1148 $ hg incoming --bundle ../issue3805.hg
1149 1149 comparing with $TESTTMP/tmpe/repo-issue3805
1150 1150 searching for changes
1151 1151 2:323a9c3ddd91 (draft) [tip ] A
1152 1152 $ hg outgoing
1153 1153 comparing with $TESTTMP/tmpe/repo-issue3805
1154 1154 searching for changes
1155 1155 1:29f0c6921ddd (draft) [tip ] A
1156 1156
1157 1157 #if serve
1158 1158
1159 1159 $ hg serve -R ../repo-issue3805 -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
1160 1160 $ cat hg.pid >> $DAEMON_PIDS
1161 1161
1162 1162 $ hg incoming http://localhost:$HGPORT
1163 1163 comparing with http://localhost:$HGPORT/
1164 1164 searching for changes
1165 1165 2:323a9c3ddd91 (draft) [tip ] A
1166 1166 $ hg outgoing http://localhost:$HGPORT
1167 1167 comparing with http://localhost:$HGPORT/
1168 1168 searching for changes
1169 1169 1:29f0c6921ddd (draft) [tip ] A
1170 1170
1171 1171 $ killdaemons.py
1172 1172
1173 1173 #endif
1174 1174
1175 1175 This test issue 3814
1176 1176
1177 1177 (nothing to push but locally hidden changeset)
1178 1178
1179 1179 $ cd ..
1180 1180 $ hg init repo-issue3814
1181 1181 $ cd repo-issue3805
1182 1182 $ hg push -r 323a9c3ddd91 ../repo-issue3814
1183 1183 pushing to ../repo-issue3814
1184 1184 searching for changes
1185 1185 adding changesets
1186 1186 adding manifests
1187 1187 adding file changes
1188 1188 added 2 changesets with 2 changes to 2 files
1189 1189 1 new obsolescence markers
1190 1190 $ hg out ../repo-issue3814
1191 1191 comparing with ../repo-issue3814
1192 1192 searching for changes
1193 1193 no changes found
1194 1194 [1]
1195 1195
1196 1196 Test that a local tag blocks a changeset from being hidden
1197 1197
1198 1198 $ hg tag -l visible -r 1 --hidden
1199 1199 $ hg log -G
1200 1200 @ 2:323a9c3ddd91 (draft) [tip ] A
1201 1201 |
1202 1202 | x 1:29f0c6921ddd (draft *obsolete*) [visible ] A [rewritten using amend as 2:323a9c3ddd91]
1203 1203 |/
1204 1204 o 0:d20a80d4def3 (draft) [ ] base
1205 1205
1206 1206 Test that removing a local tag does not cause some commands to fail
1207 1207
1208 1208 $ hg tag -l -r tip tiptag
1209 1209 $ hg tags
1210 1210 tiptag 2:323a9c3ddd91
1211 1211 tip 2:323a9c3ddd91
1212 1212 visible 1:29f0c6921ddd
1213 1213 $ hg --config extensions.strip= strip -r tip --no-backup
1214 1214 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1215 1215 $ hg tags
1216 1216 visible 1:29f0c6921ddd
1217 1217 tip 1:29f0c6921ddd
1218 1218
1219 1219 Test bundle overlay onto hidden revision
1220 1220
1221 1221 $ cd ..
1222 1222 $ hg init repo-bundleoverlay
1223 1223 $ cd repo-bundleoverlay
1224 1224 $ echo "A" > foo
1225 1225 $ hg ci -Am "A"
1226 1226 adding foo
1227 1227 $ echo "B" >> foo
1228 1228 $ hg ci -m "B"
1229 1229 $ hg up 0
1230 1230 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1231 1231 $ echo "C" >> foo
1232 1232 $ hg ci -m "C"
1233 1233 created new head
1234 1234 $ hg log -G
1235 1235 @ 2:c186d7714947 (draft) [tip ] C
1236 1236 |
1237 1237 | o 1:44526ebb0f98 (draft) [ ] B
1238 1238 |/
1239 1239 o 0:4b34ecfb0d56 (draft) [ ] A
1240 1240
1241 1241
1242 1242 $ hg clone -r1 . ../other-bundleoverlay
1243 1243 adding changesets
1244 1244 adding manifests
1245 1245 adding file changes
1246 1246 added 2 changesets with 2 changes to 1 files
1247 1247 new changesets 4b34ecfb0d56:44526ebb0f98
1248 1248 updating to branch default
1249 1249 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1250 1250 $ cd ../other-bundleoverlay
1251 1251 $ echo "B+" >> foo
1252 1252 $ hg ci --amend -m "B+"
1253 1253 $ hg log -G --hidden
1254 1254 @ 2:b7d587542d40 (draft) [tip ] B+
1255 1255 |
1256 1256 | x 1:44526ebb0f98 (draft *obsolete*) [ ] B [rewritten using amend as 2:b7d587542d40]
1257 1257 |/
1258 1258 o 0:4b34ecfb0d56 (draft) [ ] A
1259 1259
1260 1260
1261 1261 #if repobundlerepo
1262 1262 $ hg incoming ../repo-bundleoverlay --bundle ../bundleoverlay.hg
1263 1263 comparing with ../repo-bundleoverlay
1264 1264 searching for changes
1265 1265 1:44526ebb0f98 (draft) [ ] B
1266 1266 2:c186d7714947 (draft) [tip ] C
1267 1267 $ hg log -G -R ../bundleoverlay.hg
1268 1268 o 3:c186d7714947 (draft) [tip ] C
1269 1269 |
1270 1270 | @ 2:b7d587542d40 (draft) [ ] B+
1271 1271 |/
1272 1272 o 0:4b34ecfb0d56 (draft) [ ] A
1273 1273
1274 1274 #endif
1275 1275
1276 1276 #if serve
1277 1277
1278 1278 Test issue 4506
1279 1279
1280 1280 $ cd ..
1281 1281 $ hg init repo-issue4506
1282 1282 $ cd repo-issue4506
1283 1283 $ echo "0" > foo
1284 1284 $ hg add foo
1285 1285 $ hg ci -m "content-0"
1286 1286
1287 1287 $ hg up null
1288 1288 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1289 1289 $ echo "1" > bar
1290 1290 $ hg add bar
1291 1291 $ hg ci -m "content-1"
1292 1292 created new head
1293 1293 $ hg up 0
1294 1294 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1295 1295 $ hg graft 1
1296 1296 grafting 1:1c9eddb02162 "content-1" (tip)
1297 1297
1298 1298 $ hg debugobsolete `hg log -r1 -T'{node}'` `hg log -r2 -T'{node}'`
1299 1299 obsoleted 1 changesets
1300 1300
1301 1301 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
1302 1302 $ cat hg.pid >> $DAEMON_PIDS
1303 1303
1304 1304 $ get-with-headers.py --headeronly localhost:$HGPORT 'rev/1'
1305 1305 404 Not Found
1306 1306 [1]
1307 1307 $ get-with-headers.py --headeronly localhost:$HGPORT 'file/tip/bar'
1308 1308 200 Script output follows
1309 1309 $ get-with-headers.py --headeronly localhost:$HGPORT 'annotate/tip/bar'
1310 1310 200 Script output follows
1311 1311
1312 1312 $ killdaemons.py
1313 1313
1314 1314 #endif
1315 1315
1316 1316 Test heads computation on pending index changes with obsolescence markers
1317 1317 $ cd ..
1318 1318 $ cat >$TESTTMP/test_extension.py << EOF
1319 1319 > from __future__ import absolute_import
1320 1320 > from mercurial.i18n import _
1321 1321 > from mercurial import cmdutil, registrar
1322 1322 >
1323 1323 > cmdtable = {}
1324 1324 > command = registrar.command(cmdtable)
1325 1325 > @command(b"amendtransient",[], _(b'hg amendtransient [rev]'))
1326 1326 > def amend(ui, repo, *pats, **opts):
1327 1327 > opts['message'] = 'Test'
1328 1328 > opts['logfile'] = None
1329 1329 > cmdutil.amend(ui, repo, repo['.'], {}, pats, opts)
1330 1330 > ui.write(b'%s\n' % repo.changelog.headrevs())
1331 1331 > EOF
1332 1332 $ cat >> $HGRCPATH << EOF
1333 1333 > [extensions]
1334 1334 > testextension=$TESTTMP/test_extension.py
1335 1335 > EOF
1336 1336 $ hg init repo-issue-nativerevs-pending-changes
1337 1337 $ cd repo-issue-nativerevs-pending-changes
1338 1338 $ mkcommit a
1339 1339 $ mkcommit b
1340 1340 $ hg up ".^"
1341 1341 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1342 1342 $ echo aa > a
1343 1343 $ hg amendtransient
1344 1344 1 new orphan changesets
1345 1345 [1, 2]
1346 1346
1347 1347 Test cache consistency for the visible filter
1348 1348 1) We want to make sure that the cached filtered revs are invalidated when
1349 1349 bookmarks change
1350 1350 $ cd ..
1351 1351 $ cat >$TESTTMP/test_extension.py << EOF
1352 1352 > from __future__ import absolute_import, print_function
1353 1353 > import weakref
1354 1354 > from mercurial import (
1355 1355 > bookmarks,
1356 1356 > cmdutil,
1357 1357 > extensions,
1358 1358 > repoview,
1359 1359 > )
1360 1360 > def _bookmarkchanged(orig, bkmstoreinst, *args, **kwargs):
1361 1361 > reporef = weakref.ref(bkmstoreinst._repo)
1362 1362 > def trhook(tr):
1363 1363 > repo = reporef()
1364 1364 > hidden1 = repoview.computehidden(repo)
1365 1365 > hidden = repoview.filterrevs(repo, b'visible')
1366 1366 > if sorted(hidden1) != sorted(hidden):
1367 1367 > print("cache inconsistency")
1368 1368 > bkmstoreinst._repo.currenttransaction().addpostclose('test_extension', trhook)
1369 1369 > orig(bkmstoreinst, *args, **kwargs)
1370 1370 > def extsetup(ui):
1371 1371 > extensions.wrapfunction(bookmarks.bmstore, '_recordchange',
1372 1372 > _bookmarkchanged)
1373 1373 > EOF
1374 1374
1375 1375 $ hg init repo-cache-inconsistency
1376 1376 $ cd repo-issue-nativerevs-pending-changes
1377 1377 $ mkcommit a
1378 1378 a already tracked!
1379 1379 $ mkcommit b
1380 1380 $ hg id
1381 1381 13bedc178fce tip
1382 1382 $ echo "hello" > b
1383 1383 $ hg commit --amend -m "message"
1384 1384 $ hg book bookb -r 13bedc178fce --hidden
1385 1385 bookmarking hidden changeset 13bedc178fce
1386 1386 (hidden revision '13bedc178fce' was rewritten as: a9b1f8652753)
1387 1387 $ hg log -r 13bedc178fce
1388 1388 4:13bedc178fce (draft *obsolete*) [ bookb] add b [rewritten using amend as 5:a9b1f8652753]
1389 1389 $ hg book -d bookb
1390 1390 $ hg log -r 13bedc178fce
1391 1391 abort: hidden revision '13bedc178fce' was rewritten as: a9b1f8652753!
1392 1392 (use --hidden to access hidden revisions)
1393 1393 [255]
1394 1394
1395 1395 Empty out the test extension, as it isn't compatible with later parts
1396 1396 of the test.
1397 1397 $ echo > $TESTTMP/test_extension.py
1398 1398
1399 1399 Test ability to pull changeset with locally applying obsolescence markers
1400 1400 (issue4945)
1401 1401
1402 1402 $ cd ..
1403 1403 $ hg init issue4845
1404 1404 $ cd issue4845
1405 1405
1406 1406 $ echo foo > f0
1407 1407 $ hg add f0
1408 1408 $ hg ci -m '0'
1409 1409 $ echo foo > f1
1410 1410 $ hg add f1
1411 1411 $ hg ci -m '1'
1412 1412 $ echo foo > f2
1413 1413 $ hg add f2
1414 1414 $ hg ci -m '2'
1415 1415
1416 1416 $ echo bar > f2
1417 1417 $ hg commit --amend --config experimental.evolution.createmarkers=True
1418 1418 $ hg log -G
1419 1419 @ 3:b0551702f918 (draft) [tip ] 2
1420 1420 |
1421 1421 o 1:e016b03fd86f (draft) [ ] 1
1422 1422 |
1423 1423 o 0:a78f55e5508c (draft) [ ] 0
1424 1424
1425 1425 $ hg log -G --hidden
1426 1426 @ 3:b0551702f918 (draft) [tip ] 2
1427 1427 |
1428 1428 | x 2:e008cf283490 (draft *obsolete*) [ ] 2 [rewritten using amend as 3:b0551702f918]
1429 1429 |/
1430 1430 o 1:e016b03fd86f (draft) [ ] 1
1431 1431 |
1432 1432 o 0:a78f55e5508c (draft) [ ] 0
1433 1433
1434 1434
1435 1435 $ hg strip --hidden -r 2 --config extensions.strip= --config devel.strip-obsmarkers=no
1436 1436 saved backup bundle to $TESTTMP/tmpe/issue4845/.hg/strip-backup/e008cf283490-ede36964-backup.hg
1437 1437 $ hg debugobsolete
1438 1438 e008cf2834908e5d6b0f792a9d4b0e2272260fb8 b0551702f918510f01ae838ab03a463054c67b46 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
1439 1439 $ hg log -G
1440 1440 @ 2:b0551702f918 (draft) [tip ] 2
1441 1441 |
1442 1442 o 1:e016b03fd86f (draft) [ ] 1
1443 1443 |
1444 1444 o 0:a78f55e5508c (draft) [ ] 0
1445 1445
1446 1446 $ hg log -G --hidden
1447 1447 @ 2:b0551702f918 (draft) [tip ] 2
1448 1448 |
1449 1449 o 1:e016b03fd86f (draft) [ ] 1
1450 1450 |
1451 1451 o 0:a78f55e5508c (draft) [ ] 0
1452 1452
1453 1453 $ hg debugbundle .hg/strip-backup/e008cf283490-*-backup.hg
1454 1454 Stream params: {Compression: BZ}
1455 changegroup -- {nbchanges: 1, version: 02}
1455 changegroup -- {nbchanges: 1, version: 02} (mandatory: True)
1456 1456 e008cf2834908e5d6b0f792a9d4b0e2272260fb8
1457 cache:rev-branch-cache -- {}
1458 phase-heads -- {}
1457 cache:rev-branch-cache -- {} (mandatory: True)
1458 phase-heads -- {} (mandatory: True)
1459 1459 e008cf2834908e5d6b0f792a9d4b0e2272260fb8 draft
1460 1460
1461 1461 #if repobundlerepo
1462 1462 $ hg pull .hg/strip-backup/e008cf283490-*-backup.hg
1463 1463 pulling from .hg/strip-backup/e008cf283490-ede36964-backup.hg
1464 1464 searching for changes
1465 1465 no changes found
1466 1466 #endif
1467 1467 $ hg debugobsolete
1468 1468 e008cf2834908e5d6b0f792a9d4b0e2272260fb8 b0551702f918510f01ae838ab03a463054c67b46 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
1469 1469 $ hg log -G
1470 1470 @ 2:b0551702f918 (draft) [tip ] 2
1471 1471 |
1472 1472 o 1:e016b03fd86f (draft) [ ] 1
1473 1473 |
1474 1474 o 0:a78f55e5508c (draft) [ ] 0
1475 1475
1476 1476 $ hg log -G --hidden
1477 1477 @ 2:b0551702f918 (draft) [tip ] 2
1478 1478 |
1479 1479 o 1:e016b03fd86f (draft) [ ] 1
1480 1480 |
1481 1481 o 0:a78f55e5508c (draft) [ ] 0
1482 1482
1483 1483
1484 1484 Testing that strip remove markers:
1485 1485
1486 1486 $ hg strip -r 1 --config extensions.strip=
1487 1487 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
1488 1488 saved backup bundle to $TESTTMP/tmpe/issue4845/.hg/strip-backup/e016b03fd86f-65ede734-backup.hg
1489 1489 $ hg debugobsolete
1490 1490 $ hg log -G
1491 1491 @ 0:a78f55e5508c (draft) [tip ] 0
1492 1492
1493 1493 $ hg log -G --hidden
1494 1494 @ 0:a78f55e5508c (draft) [tip ] 0
1495 1495
1496 1496 $ hg debugbundle .hg/strip-backup/e016b03fd86f-*-backup.hg
1497 1497 Stream params: {Compression: BZ}
1498 changegroup -- {nbchanges: 2, version: 02}
1498 changegroup -- {nbchanges: 2, version: 02} (mandatory: True)
1499 1499 e016b03fd86fcccc54817d120b90b751aaf367d6
1500 1500 b0551702f918510f01ae838ab03a463054c67b46
1501 cache:rev-branch-cache -- {}
1502 obsmarkers -- {}
1501 cache:rev-branch-cache -- {} (mandatory: True)
1502 obsmarkers -- {} (mandatory: True)
1503 1503 version: 1 (92 bytes)
1504 1504 e008cf2834908e5d6b0f792a9d4b0e2272260fb8 b0551702f918510f01ae838ab03a463054c67b46 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
1505 phase-heads -- {}
1505 phase-heads -- {} (mandatory: True)
1506 1506 b0551702f918510f01ae838ab03a463054c67b46 draft
1507 1507
1508 1508 $ hg unbundle .hg/strip-backup/e016b03fd86f-*-backup.hg
1509 1509 adding changesets
1510 1510 adding manifests
1511 1511 adding file changes
1512 1512 added 2 changesets with 2 changes to 2 files
1513 1513 1 new obsolescence markers
1514 1514 new changesets e016b03fd86f:b0551702f918
1515 1515 (run 'hg update' to get a working copy)
1516 1516 $ hg debugobsolete | sort
1517 1517 e008cf2834908e5d6b0f792a9d4b0e2272260fb8 b0551702f918510f01ae838ab03a463054c67b46 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
1518 1518 $ hg log -G
1519 1519 o 2:b0551702f918 (draft) [tip ] 2
1520 1520 |
1521 1521 o 1:e016b03fd86f (draft) [ ] 1
1522 1522 |
1523 1523 @ 0:a78f55e5508c (draft) [ ] 0
1524 1524
1525 1525 $ hg log -G --hidden
1526 1526 o 2:b0551702f918 (draft) [tip ] 2
1527 1527 |
1528 1528 o 1:e016b03fd86f (draft) [ ] 1
1529 1529 |
1530 1530 @ 0:a78f55e5508c (draft) [ ] 0
1531 1531
1532 1532 Test that 'hg debugobsolete --index --rev' can show indices of obsmarkers when
1533 1533 only a subset of those are displayed (because of --rev option)
1534 1534 $ hg init doindexrev
1535 1535 $ cd doindexrev
1536 1536 $ echo a > a
1537 1537 $ hg ci -Am a
1538 1538 adding a
1539 1539 $ hg ci --amend -m aa
1540 1540 $ echo b > b
1541 1541 $ hg ci -Am b
1542 1542 adding b
1543 1543 $ hg ci --amend -m bb
1544 1544 $ echo c > c
1545 1545 $ hg ci -Am c
1546 1546 adding c
1547 1547 $ hg ci --amend -m cc
1548 1548 $ echo d > d
1549 1549 $ hg ci -Am d
1550 1550 adding d
1551 1551 $ hg ci --amend -m dd --config experimental.evolution.track-operation=1
1552 1552 $ hg debugobsolete --index --rev "3+7"
1553 1553 1 6fdef60fcbabbd3d50e9b9cbc2a240724b91a5e1 d27fb9b066076fd921277a4b9e8b9cb48c95bc6a 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
1554 1554 3 4715cf767440ed891755448016c2b8cf70760c30 7ae79c5d60f049c7b0dd02f5f25b9d60aaf7b36d 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
1555 1555 $ hg debugobsolete --index --rev "3+7" -Tjson
1556 1556 [
1557 1557 {
1558 1558 "date": [0, 0],
1559 1559 "flag": 0,
1560 1560 "index": 1,
1561 1561 "metadata": {"ef1": "1", "operation": "amend", "user": "test"},
1562 1562 "prednode": "6fdef60fcbabbd3d50e9b9cbc2a240724b91a5e1",
1563 1563 "succnodes": ["d27fb9b066076fd921277a4b9e8b9cb48c95bc6a"]
1564 1564 },
1565 1565 {
1566 1566 "date": [0, 0],
1567 1567 "flag": 0,
1568 1568 "index": 3,
1569 1569 "metadata": {"ef1": "1", "operation": "amend", "user": "test"},
1570 1570 "prednode": "4715cf767440ed891755448016c2b8cf70760c30",
1571 1571 "succnodes": ["7ae79c5d60f049c7b0dd02f5f25b9d60aaf7b36d"]
1572 1572 }
1573 1573 ]
1574 1574
1575 1575 Test the --delete option of debugobsolete command
1576 1576 $ hg debugobsolete --index
1577 1577 0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b f9bd49731b0b175e42992a3c8fa6c678b2bc11f1 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
1578 1578 1 6fdef60fcbabbd3d50e9b9cbc2a240724b91a5e1 d27fb9b066076fd921277a4b9e8b9cb48c95bc6a 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
1579 1579 2 1ab51af8f9b41ef8c7f6f3312d4706d870b1fb74 29346082e4a9e27042b62d2da0e2de211c027621 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
1580 1580 3 4715cf767440ed891755448016c2b8cf70760c30 7ae79c5d60f049c7b0dd02f5f25b9d60aaf7b36d 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
1581 1581 $ hg debugobsolete --delete 1 --delete 3
1582 1582 deleted 2 obsolescence markers
1583 1583 $ hg debugobsolete
1584 1584 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b f9bd49731b0b175e42992a3c8fa6c678b2bc11f1 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
1585 1585 1ab51af8f9b41ef8c7f6f3312d4706d870b1fb74 29346082e4a9e27042b62d2da0e2de211c027621 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
1586 1586
1587 1587 Test adding changeset after obsmarkers affecting it
1588 1588 (eg: during pull, or unbundle)
1589 1589
1590 1590 $ mkcommit e
1591 1591 $ hg bundle -r . --base .~1 ../bundle-2.hg
1592 1592 1 changesets found
1593 1593 $ getid .
1594 1594 $ hg --config extensions.strip= strip -r .
1595 1595 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1596 1596 saved backup bundle to $TESTTMP/tmpe/issue4845/doindexrev/.hg/strip-backup/9bc153528424-ee80edd4-backup.hg
1597 1597 $ hg debugobsolete 9bc153528424ea266d13e57f9ff0d799dfe61e4b
1598 1598 $ hg unbundle ../bundle-2.hg
1599 1599 adding changesets
1600 1600 adding manifests
1601 1601 adding file changes
1602 1602 added 1 changesets with 1 changes to 1 files
1603 1603 (run 'hg update' to get a working copy)
1604 1604 $ hg log -G
1605 1605 @ 7:7ae79c5d60f0 (draft) [tip ] dd
1606 1606 |
1607 1607 | o 6:4715cf767440 (draft) [ ] d
1608 1608 |/
1609 1609 o 5:29346082e4a9 (draft) [ ] cc
1610 1610 |
1611 1611 o 3:d27fb9b06607 (draft) [ ] bb
1612 1612 |
1613 1613 | o 2:6fdef60fcbab (draft) [ ] b
1614 1614 |/
1615 1615 o 1:f9bd49731b0b (draft) [ ] aa
1616 1616
1617 1617
1618 1618 $ cd ..
@@ -1,1805 +1,1805 b''
1 1 $ cat <<EOF >> $HGRCPATH
2 2 > [extensions]
3 3 > mq =
4 4 > shelve =
5 5 > [defaults]
6 6 > diff = --nodates --git
7 7 > qnew = --date '0 0'
8 8 > [shelve]
9 9 > maxbackups = 2
10 10 > EOF
11 11
12 12 $ hg init repo
13 13 $ cd repo
14 14 $ mkdir a b
15 15 $ echo a > a/a
16 16 $ echo b > b/b
17 17 $ echo c > c
18 18 $ echo d > d
19 19 $ echo x > x
20 20 $ hg addremove -q
21 21
22 22 shelve has a help message
23 23 $ hg shelve -h
24 24 hg shelve [OPTION]... [FILE]...
25 25
26 26 save and set aside changes from the working directory
27 27
28 28 Shelving takes files that "hg status" reports as not clean, saves the
29 29 modifications to a bundle (a shelved change), and reverts the files so
30 30 that their state in the working directory becomes clean.
31 31
32 32 To restore these changes to the working directory, using "hg unshelve";
33 33 this will work even if you switch to a different commit.
34 34
35 35 When no files are specified, "hg shelve" saves all not-clean files. If
36 36 specific files or directories are named, only changes to those files are
37 37 shelved.
38 38
39 39 In bare shelve (when no files are specified, without interactive, include
40 40 and exclude option), shelving remembers information if the working
41 41 directory was on newly created branch, in other words working directory
42 42 was on different branch than its first parent. In this situation
43 43 unshelving restores branch information to the working directory.
44 44
45 45 Each shelved change has a name that makes it easier to find later. The
46 46 name of a shelved change defaults to being based on the active bookmark,
47 47 or if there is no active bookmark, the current named branch. To specify a
48 48 different name, use "--name".
49 49
50 50 To see a list of existing shelved changes, use the "--list" option. For
51 51 each shelved change, this will print its name, age, and description; use "
52 52 --patch" or "--stat" for more details.
53 53
54 54 To delete specific shelved changes, use "--delete". To delete all shelved
55 55 changes, use "--cleanup".
56 56
57 57 (use 'hg help -e shelve' to show help for the shelve extension)
58 58
59 59 options ([+] can be repeated):
60 60
61 61 -A --addremove mark new/missing files as added/removed before
62 62 shelving
63 63 -u --unknown store unknown files in the shelve
64 64 --cleanup delete all shelved changes
65 65 --date DATE shelve with the specified commit date
66 66 -d --delete delete the named shelved change(s)
67 67 -e --edit invoke editor on commit messages
68 68 -l --list list current shelves
69 69 -m --message TEXT use text as shelve message
70 70 -n --name NAME use the given name for the shelved commit
71 71 -p --patch show patch
72 72 -i --interactive interactive mode, only works while creating a shelve
73 73 --stat output diffstat-style summary of changes
74 74 -I --include PATTERN [+] include names matching the given patterns
75 75 -X --exclude PATTERN [+] exclude names matching the given patterns
76 76 --mq operate on patch repository
77 77
78 78 (some details hidden, use --verbose to show complete help)
79 79
80 80 shelving in an empty repo should be possible
81 81 (this tests also that editor is not invoked, if '--edit' is not
82 82 specified)
83 83
84 84 $ HGEDITOR=cat hg shelve
85 85 shelved as default
86 86 0 files updated, 0 files merged, 5 files removed, 0 files unresolved
87 87
88 88 $ hg unshelve
89 89 unshelving change 'default'
90 90
91 91 $ hg commit -q -m 'initial commit'
92 92
93 93 $ hg shelve
94 94 nothing changed
95 95 [1]
96 96
97 97 make sure shelve files were backed up
98 98
99 99 $ ls .hg/shelve-backup
100 100 default.hg
101 101 default.patch
102 102
103 103 checks to make sure we dont create a directory or
104 104 hidden file while choosing a new shelve name
105 105
106 106 when we are given a name
107 107
108 108 $ hg shelve -n foo/bar
109 109 abort: shelved change names can not contain slashes
110 110 [255]
111 111 $ hg shelve -n .baz
112 112 abort: shelved change names can not start with '.'
113 113 [255]
114 114 $ hg shelve -n foo\\bar
115 115 abort: shelved change names can not contain slashes
116 116 [255]
117 117
118 118 when shelve has to choose itself
119 119
120 120 $ hg branch x/y -q
121 121 $ hg commit -q -m "Branch commit 0"
122 122 $ hg shelve
123 123 nothing changed
124 124 [1]
125 125 $ hg branch .x -q
126 126 $ hg commit -q -m "Branch commit 1"
127 127 $ hg shelve
128 128 nothing changed
129 129 [1]
130 130 $ hg branch x\\y -q
131 131 $ hg commit -q -m "Branch commit 2"
132 132 $ hg shelve
133 133 nothing changed
134 134 [1]
135 135
136 136 cleaning the branches made for name checking tests
137 137
138 138 $ hg up default -q
139 139 $ hg strip 3 -q
140 140 $ hg strip 2 -q
141 141 $ hg strip 1 -q
142 142
143 143 create an mq patch - shelving should work fine with a patch applied
144 144
145 145 $ echo n > n
146 146 $ hg add n
147 147 $ hg commit n -m second
148 148 $ hg qnew second.patch
149 149
150 150 shelve a change that we will delete later
151 151
152 152 $ echo a >> a/a
153 153 $ hg shelve
154 154 shelved as default
155 155 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
156 156
157 157 set up some more complex changes to shelve
158 158
159 159 $ echo a >> a/a
160 160 $ hg mv b b.rename
161 161 moving b/b to b.rename/b
162 162 $ hg cp c c.copy
163 163 $ hg status -C
164 164 M a/a
165 165 A b.rename/b
166 166 b/b
167 167 A c.copy
168 168 c
169 169 R b/b
170 170
171 171 the common case - no options or filenames
172 172
173 173 $ hg shelve
174 174 shelved as default-01
175 175 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
176 176 $ hg status -C
177 177
178 178 ensure that our shelved changes exist
179 179
180 180 $ hg shelve -l
181 181 default-01 (*)* changes to: [mq]: second.patch (glob)
182 182 default (*)* changes to: [mq]: second.patch (glob)
183 183
184 184 $ hg shelve -l -p default
185 185 default (*)* changes to: [mq]: second.patch (glob)
186 186
187 187 diff --git a/a/a b/a/a
188 188 --- a/a/a
189 189 +++ b/a/a
190 190 @@ -1,1 +1,2 @@
191 191 a
192 192 +a
193 193
194 194 $ hg shelve --list --addremove
195 195 abort: options '--list' and '--addremove' may not be used together
196 196 [255]
197 197
198 198 delete our older shelved change
199 199
200 200 $ hg shelve -d default
201 201 $ hg qfinish -a -q
202 202
203 203 ensure shelve backups aren't overwritten
204 204
205 205 $ ls .hg/shelve-backup/
206 206 default-1.hg
207 207 default-1.patch
208 208 default.hg
209 209 default.patch
210 210
211 211 local edits should not prevent a shelved change from applying
212 212
213 213 $ printf "z\na\n" > a/a
214 214 $ hg unshelve --keep
215 215 unshelving change 'default-01'
216 216 temporarily committing pending changes (restore with 'hg unshelve --abort')
217 217 rebasing shelved changes
218 218 rebasing 4:32c69314e062 "changes to: [mq]: second.patch" (tip)
219 219 merging a/a
220 220
221 221 $ hg revert --all -q
222 222 $ rm a/a.orig b.rename/b c.copy
223 223
224 224 apply it and make sure our state is as expected
225 225
226 226 (this also tests that same timestamp prevents backups from being
227 227 removed, even though there are more than 'maxbackups' backups)
228 228
229 229 $ f -t .hg/shelve-backup/default.patch
230 230 .hg/shelve-backup/default.patch: file
231 231 $ touch -t 200001010000 .hg/shelve-backup/default.patch
232 232 $ f -t .hg/shelve-backup/default-1.patch
233 233 .hg/shelve-backup/default-1.patch: file
234 234 $ touch -t 200001010000 .hg/shelve-backup/default-1.patch
235 235
236 236 $ hg unshelve
237 237 unshelving change 'default-01'
238 238 $ hg status -C
239 239 M a/a
240 240 A b.rename/b
241 241 b/b
242 242 A c.copy
243 243 c
244 244 R b/b
245 245 $ hg shelve -l
246 246
247 247 (both of default.hg and default-1.hg should be still kept, because it
248 248 is difficult to decide actual order of them from same timestamp)
249 249
250 250 $ ls .hg/shelve-backup/
251 251 default-01.hg
252 252 default-01.patch
253 253 default-1.hg
254 254 default-1.patch
255 255 default.hg
256 256 default.patch
257 257
258 258 $ hg unshelve
259 259 abort: no shelved changes to apply!
260 260 [255]
261 261 $ hg unshelve foo
262 262 abort: shelved change 'foo' not found
263 263 [255]
264 264
265 265 named shelves, specific filenames, and "commit messages" should all work
266 266 (this tests also that editor is invoked, if '--edit' is specified)
267 267
268 268 $ hg status -C
269 269 M a/a
270 270 A b.rename/b
271 271 b/b
272 272 A c.copy
273 273 c
274 274 R b/b
275 275 $ HGEDITOR=cat hg shelve -q -n wibble -m wat -e a
276 276 wat
277 277
278 278
279 279 HG: Enter commit message. Lines beginning with 'HG:' are removed.
280 280 HG: Leave message empty to abort commit.
281 281 HG: --
282 282 HG: user: shelve@localhost
283 283 HG: branch 'default'
284 284 HG: changed a/a
285 285
286 286 expect "a" to no longer be present, but status otherwise unchanged
287 287
288 288 $ hg status -C
289 289 A b.rename/b
290 290 b/b
291 291 A c.copy
292 292 c
293 293 R b/b
294 294 $ hg shelve -l --stat
295 295 wibble (*) wat (glob)
296 296 a/a | 1 +
297 297 1 files changed, 1 insertions(+), 0 deletions(-)
298 298
299 299 and now "a/a" should reappear
300 300
301 301 $ cd a
302 302 $ hg unshelve -q wibble
303 303 $ cd ..
304 304 $ hg status -C
305 305 M a/a
306 306 A b.rename/b
307 307 b/b
308 308 A c.copy
309 309 c
310 310 R b/b
311 311
312 312 ensure old shelve backups are being deleted automatically
313 313
314 314 $ ls .hg/shelve-backup/
315 315 default-01.hg
316 316 default-01.patch
317 317 wibble.hg
318 318 wibble.patch
319 319
320 320 cause unshelving to result in a merge with 'a' conflicting
321 321
322 322 $ hg shelve -q
323 323 $ echo c>>a/a
324 324 $ hg commit -m second
325 325 $ hg tip --template '{files}\n'
326 326 a/a
327 327
328 328 add an unrelated change that should be preserved
329 329
330 330 $ mkdir foo
331 331 $ echo foo > foo/foo
332 332 $ hg add foo/foo
333 333
334 334 force a conflicted merge to occur
335 335
336 336 $ hg unshelve
337 337 unshelving change 'default'
338 338 temporarily committing pending changes (restore with 'hg unshelve --abort')
339 339 rebasing shelved changes
340 340 rebasing 5:32c69314e062 "changes to: [mq]: second.patch" (tip)
341 341 merging a/a
342 342 warning: conflicts while merging a/a! (edit, then use 'hg resolve --mark')
343 343 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
344 344 [1]
345 345 $ hg status -v
346 346 M a/a
347 347 M b.rename/b
348 348 M c.copy
349 349 R b/b
350 350 ? a/a.orig
351 351 # The repository is in an unfinished *unshelve* state.
352 352
353 353 # Unresolved merge conflicts:
354 354 #
355 355 # a/a
356 356 #
357 357 # To mark files as resolved: hg resolve --mark FILE
358 358
359 359 # To continue: hg unshelve --continue
360 360 # To abort: hg unshelve --abort
361 361
362 362
363 363 ensure that we have a merge with unresolved conflicts
364 364
365 365 $ hg heads -q --template '{rev}\n'
366 366 5
367 367 4
368 368 $ hg parents -q --template '{rev}\n'
369 369 4
370 370 5
371 371 $ hg status
372 372 M a/a
373 373 M b.rename/b
374 374 M c.copy
375 375 R b/b
376 376 ? a/a.orig
377 377 $ hg diff
378 378 diff --git a/a/a b/a/a
379 379 --- a/a/a
380 380 +++ b/a/a
381 381 @@ -1,2 +1,6 @@
382 382 a
383 383 +<<<<<<< dest: * - shelve: pending changes temporary commit (glob)
384 384 c
385 385 +=======
386 386 +a
387 387 +>>>>>>> source: 32c69314e062 - shelve: changes to: [mq]: second.patch
388 388 diff --git a/b/b b/b.rename/b
389 389 rename from b/b
390 390 rename to b.rename/b
391 391 diff --git a/c b/c.copy
392 392 copy from c
393 393 copy to c.copy
394 394 $ hg resolve -l
395 395 U a/a
396 396
397 397 $ hg shelve
398 398 abort: unshelve already in progress
399 399 (use 'hg unshelve --continue' or 'hg unshelve --abort')
400 400 [255]
401 401
402 402 abort the unshelve and be happy
403 403
404 404 $ hg status
405 405 M a/a
406 406 M b.rename/b
407 407 M c.copy
408 408 R b/b
409 409 ? a/a.orig
410 410 $ hg unshelve -a
411 411 rebase aborted
412 412 unshelve of 'default' aborted
413 413 $ hg heads -q
414 414 3:2e69b451d1ea
415 415 $ hg parents
416 416 changeset: 3:2e69b451d1ea
417 417 tag: tip
418 418 user: test
419 419 date: Thu Jan 01 00:00:00 1970 +0000
420 420 summary: second
421 421
422 422 $ hg resolve -l
423 423 $ hg status
424 424 A foo/foo
425 425 ? a/a.orig
426 426
427 427 try to continue with no unshelve underway
428 428
429 429 $ hg unshelve -c
430 430 abort: no unshelve in progress
431 431 [255]
432 432 $ hg status
433 433 A foo/foo
434 434 ? a/a.orig
435 435
436 436 redo the unshelve to get a conflict
437 437
438 438 $ hg unshelve -q
439 439 warning: conflicts while merging a/a! (edit, then use 'hg resolve --mark')
440 440 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
441 441 [1]
442 442
443 443 attempt to continue
444 444
445 445 $ hg unshelve -c
446 446 abort: unresolved conflicts, can't continue
447 447 (see 'hg resolve', then 'hg unshelve --continue')
448 448 [255]
449 449
450 450 $ hg revert -r . a/a
451 451 $ hg resolve -m a/a
452 452 (no more unresolved files)
453 453 continue: hg unshelve --continue
454 454
455 455 $ hg commit -m 'commit while unshelve in progress'
456 456 abort: unshelve already in progress
457 457 (use 'hg unshelve --continue' or 'hg unshelve --abort')
458 458 [255]
459 459
460 460 $ hg graft --continue
461 461 abort: no graft in progress
462 462 (continue: hg unshelve --continue)
463 463 [255]
464 464 $ hg unshelve -c
465 465 rebasing 5:32c69314e062 "changes to: [mq]: second.patch" (tip)
466 466 unshelve of 'default' complete
467 467
468 468 ensure the repo is as we hope
469 469
470 470 $ hg parents
471 471 changeset: 3:2e69b451d1ea
472 472 tag: tip
473 473 user: test
474 474 date: Thu Jan 01 00:00:00 1970 +0000
475 475 summary: second
476 476
477 477 $ hg heads -q
478 478 3:2e69b451d1ea
479 479
480 480 $ hg status -C
481 481 A b.rename/b
482 482 b/b
483 483 A c.copy
484 484 c
485 485 A foo/foo
486 486 R b/b
487 487 ? a/a.orig
488 488
489 489 there should be no shelves left
490 490
491 491 $ hg shelve -l
492 492
493 493 #if execbit
494 494
495 495 ensure that metadata-only changes are shelved
496 496
497 497 $ chmod +x a/a
498 498 $ hg shelve -q -n execbit a/a
499 499 $ hg status a/a
500 500 $ hg unshelve -q execbit
501 501 $ hg status a/a
502 502 M a/a
503 503 $ hg revert a/a
504 504
505 505 #endif
506 506
507 507 #if symlink
508 508
509 509 $ rm a/a
510 510 $ ln -s foo a/a
511 511 $ hg shelve -q -n symlink a/a
512 512 $ hg status a/a
513 513 $ hg unshelve -q -n symlink
514 514 $ hg status a/a
515 515 M a/a
516 516 $ hg revert a/a
517 517
518 518 #endif
519 519
520 520 set up another conflict between a commit and a shelved change
521 521
522 522 $ hg revert -q -C -a
523 523 $ rm a/a.orig b.rename/b c.copy
524 524 $ echo a >> a/a
525 525 $ hg shelve -q
526 526 $ echo x >> a/a
527 527 $ hg ci -m 'create conflict'
528 528 $ hg add foo/foo
529 529
530 530 if we resolve a conflict while unshelving, the unshelve should succeed
531 531
532 532 $ hg unshelve --tool :merge-other --keep
533 533 unshelving change 'default'
534 534 temporarily committing pending changes (restore with 'hg unshelve --abort')
535 535 rebasing shelved changes
536 536 rebasing 6:2f694dd83a13 "changes to: second" (tip)
537 537 merging a/a
538 538 $ hg parents -q
539 539 4:33f7f61e6c5e
540 540 $ hg shelve -l
541 541 default (*)* changes to: second (glob)
542 542 $ hg status
543 543 M a/a
544 544 A foo/foo
545 545 $ cat a/a
546 546 a
547 547 c
548 548 a
549 549 $ cat > a/a << EOF
550 550 > a
551 551 > c
552 552 > x
553 553 > EOF
554 554
555 555 $ HGMERGE=true hg unshelve
556 556 unshelving change 'default'
557 557 temporarily committing pending changes (restore with 'hg unshelve --abort')
558 558 rebasing shelved changes
559 559 rebasing 6:2f694dd83a13 "changes to: second" (tip)
560 560 merging a/a
561 561 note: rebase of 6:2f694dd83a13 created no changes to commit
562 562 $ hg parents -q
563 563 4:33f7f61e6c5e
564 564 $ hg shelve -l
565 565 $ hg status
566 566 A foo/foo
567 567 $ cat a/a
568 568 a
569 569 c
570 570 x
571 571
572 572 test keep and cleanup
573 573
574 574 $ hg shelve
575 575 shelved as default
576 576 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
577 577 $ hg shelve --list
578 578 default (*)* changes to: create conflict (glob)
579 579 $ hg unshelve -k
580 580 unshelving change 'default'
581 581 $ hg shelve --list
582 582 default (*)* changes to: create conflict (glob)
583 583 $ hg shelve --cleanup
584 584 $ hg shelve --list
585 585
586 586 $ hg shelve --cleanup --delete
587 587 abort: options '--cleanup' and '--delete' may not be used together
588 588 [255]
589 589 $ hg shelve --cleanup --patch
590 590 abort: options '--cleanup' and '--patch' may not be used together
591 591 [255]
592 592 $ hg shelve --cleanup --message MESSAGE
593 593 abort: options '--cleanup' and '--message' may not be used together
594 594 [255]
595 595
596 596 test bookmarks
597 597
598 598 $ hg bookmark test
599 599 $ hg bookmark
600 600 * test 4:33f7f61e6c5e
601 601 $ hg shelve
602 602 shelved as test
603 603 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
604 604 $ hg bookmark
605 605 * test 4:33f7f61e6c5e
606 606 $ hg unshelve
607 607 unshelving change 'test'
608 608 $ hg bookmark
609 609 * test 4:33f7f61e6c5e
610 610
611 611 shelve should still work even if mq is disabled
612 612
613 613 $ hg --config extensions.mq=! shelve
614 614 shelved as test
615 615 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
616 616 $ hg --config extensions.mq=! shelve --list
617 617 test (*)* changes to: create conflict (glob)
618 618 $ hg bookmark
619 619 * test 4:33f7f61e6c5e
620 620 $ hg --config extensions.mq=! unshelve
621 621 unshelving change 'test'
622 622 $ hg bookmark
623 623 * test 4:33f7f61e6c5e
624 624
625 625 shelve should leave dirstate clean (issue4055)
626 626
627 627 $ cd ..
628 628 $ hg init shelverebase
629 629 $ cd shelverebase
630 630 $ printf 'x\ny\n' > x
631 631 $ echo z > z
632 632 $ hg commit -Aqm xy
633 633 $ echo z >> x
634 634 $ hg commit -Aqm z
635 635 $ hg up 0
636 636 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
637 637 $ printf 'a\nx\ny\nz\n' > x
638 638 $ hg commit -Aqm xyz
639 639 $ echo c >> z
640 640 $ hg shelve
641 641 shelved as default
642 642 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
643 643 $ hg rebase -d 1 --config extensions.rebase=
644 644 rebasing 2:323bfa07f744 "xyz" (tip)
645 645 merging x
646 646 saved backup bundle to $TESTTMP/shelverebase/.hg/strip-backup/323bfa07f744-78114325-rebase.hg
647 647 $ hg unshelve
648 648 unshelving change 'default'
649 649 rebasing shelved changes
650 650 rebasing 4:82a0d7d6ba61 "changes to: xyz" (tip)
651 651 $ hg status
652 652 M z
653 653
654 654 $ cd ..
655 655
656 656 shelve should only unshelve pending changes (issue4068)
657 657
658 658 $ hg init onlypendingchanges
659 659 $ cd onlypendingchanges
660 660 $ touch a
661 661 $ hg ci -Aqm a
662 662 $ touch b
663 663 $ hg ci -Aqm b
664 664 $ hg up -q 0
665 665 $ touch c
666 666 $ hg ci -Aqm c
667 667
668 668 $ touch d
669 669 $ hg add d
670 670 $ hg shelve
671 671 shelved as default
672 672 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
673 673 $ hg up -q 1
674 674 $ hg unshelve
675 675 unshelving change 'default'
676 676 rebasing shelved changes
677 677 rebasing 3:958bcbd1776e "changes to: c" (tip)
678 678 $ hg status
679 679 A d
680 680
681 681 unshelve should work on an ancestor of the original commit
682 682
683 683 $ hg shelve
684 684 shelved as default
685 685 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
686 686 $ hg up 0
687 687 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
688 688 $ hg unshelve
689 689 unshelving change 'default'
690 690 rebasing shelved changes
691 691 rebasing 3:013284d9655e "changes to: b" (tip)
692 692 $ hg status
693 693 A d
694 694
695 695 test bug 4073 we need to enable obsolete markers for it
696 696
697 697 $ cat >> $HGRCPATH << EOF
698 698 > [experimental]
699 699 > evolution.createmarkers=True
700 700 > EOF
701 701 $ hg shelve
702 702 shelved as default
703 703 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
704 704 $ hg debugobsolete `hg --debug id -i -r 1`
705 705 obsoleted 1 changesets
706 706 $ hg unshelve
707 707 unshelving change 'default'
708 708
709 709 unshelve should leave unknown files alone (issue4113)
710 710
711 711 $ echo e > e
712 712 $ hg shelve
713 713 shelved as default
714 714 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
715 715 $ hg status
716 716 ? e
717 717 $ hg unshelve
718 718 unshelving change 'default'
719 719 $ hg status
720 720 A d
721 721 ? e
722 722 $ cat e
723 723 e
724 724
725 725 unshelve should keep a copy of unknown files
726 726
727 727 $ hg add e
728 728 $ hg shelve
729 729 shelved as default
730 730 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
731 731 $ echo z > e
732 732 $ hg unshelve
733 733 unshelving change 'default'
734 734 $ cat e
735 735 e
736 736 $ cat e.orig
737 737 z
738 738
739 739
740 740 unshelve and conflicts with tracked and untracked files
741 741
742 742 preparing:
743 743
744 744 $ rm *.orig
745 745 $ hg ci -qm 'commit stuff'
746 746 $ hg phase -p null:
747 747
748 748 no other changes - no merge:
749 749
750 750 $ echo f > f
751 751 $ hg add f
752 752 $ hg shelve
753 753 shelved as default
754 754 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
755 755 $ echo g > f
756 756 $ hg unshelve
757 757 unshelving change 'default'
758 758 $ hg st
759 759 A f
760 760 ? f.orig
761 761 $ cat f
762 762 f
763 763 $ cat f.orig
764 764 g
765 765
766 766 other uncommitted changes - merge:
767 767
768 768 $ hg st
769 769 A f
770 770 ? f.orig
771 771 $ hg shelve
772 772 shelved as default
773 773 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
774 774 #if repobundlerepo
775 775 $ hg log -G --template '{rev} {desc|firstline} {author}' -R bundle://.hg/shelved/default.hg -r 'bundle()'
776 776 o 4 changes to: commit stuff shelve@localhost
777 777 |
778 778 ~
779 779 #endif
780 780 $ hg log -G --template '{rev} {desc|firstline} {author}'
781 781 @ 3 commit stuff test
782 782 |
783 783 | o 2 c test
784 784 |/
785 785 o 0 a test
786 786
787 787 $ mv f.orig f
788 788 $ echo 1 > a
789 789 $ hg unshelve --date '1073741824 0'
790 790 unshelving change 'default'
791 791 temporarily committing pending changes (restore with 'hg unshelve --abort')
792 792 rebasing shelved changes
793 793 rebasing 5:81152db69da7 "changes to: commit stuff" (tip)
794 794 merging f
795 795 warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
796 796 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
797 797 [1]
798 798 $ hg log -G --template '{rev} {desc|firstline} {author} {date|isodate}'
799 799 @ 5 changes to: commit stuff shelve@localhost 1970-01-01 00:00 +0000
800 800 |
801 801 | @ 4 pending changes temporary commit shelve@localhost 2004-01-10 13:37 +0000
802 802 |/
803 803 o 3 commit stuff test 1970-01-01 00:00 +0000
804 804 |
805 805 | o 2 c test 1970-01-01 00:00 +0000
806 806 |/
807 807 o 0 a test 1970-01-01 00:00 +0000
808 808
809 809 $ hg st
810 810 M f
811 811 ? f.orig
812 812 $ cat f
813 813 <<<<<<< dest: 5f6b880e719b - shelve: pending changes temporary commit
814 814 g
815 815 =======
816 816 f
817 817 >>>>>>> source: 81152db69da7 - shelve: changes to: commit stuff
818 818 $ cat f.orig
819 819 g
820 820 $ hg unshelve --abort -t false
821 821 tool option will be ignored
822 822 rebase aborted
823 823 unshelve of 'default' aborted
824 824 $ hg st
825 825 M a
826 826 ? f.orig
827 827 $ cat f.orig
828 828 g
829 829 $ hg unshelve
830 830 unshelving change 'default'
831 831 temporarily committing pending changes (restore with 'hg unshelve --abort')
832 832 rebasing shelved changes
833 833 rebasing 5:81152db69da7 "changes to: commit stuff" (tip)
834 834 $ hg st
835 835 M a
836 836 A f
837 837 ? f.orig
838 838
839 839 other committed changes - merge:
840 840
841 841 $ hg shelve f
842 842 shelved as default
843 843 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
844 844 $ hg ci a -m 'intermediate other change'
845 845 $ mv f.orig f
846 846 $ hg unshelve
847 847 unshelving change 'default'
848 848 rebasing shelved changes
849 849 rebasing 5:81152db69da7 "changes to: commit stuff" (tip)
850 850 merging f
851 851 warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
852 852 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
853 853 [1]
854 854 $ hg st
855 855 M f
856 856 ? f.orig
857 857 $ cat f
858 858 <<<<<<< dest: * - test: intermediate other change (glob)
859 859 g
860 860 =======
861 861 f
862 862 >>>>>>> source: 81152db69da7 - shelve: changes to: commit stuff
863 863 $ cat f.orig
864 864 g
865 865 $ hg unshelve --abort
866 866 rebase aborted
867 867 unshelve of 'default' aborted
868 868 $ hg st
869 869 ? f.orig
870 870 $ cat f.orig
871 871 g
872 872 $ hg shelve --delete default
873 873
874 874 Recreate some conflict again
875 875
876 876 $ cd ../repo
877 877 $ hg up -C -r 3
878 878 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
879 879 (leaving bookmark test)
880 880 $ echo y >> a/a
881 881 $ hg shelve
882 882 shelved as default
883 883 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
884 884 $ hg up test
885 885 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
886 886 (activating bookmark test)
887 887 $ hg bookmark
888 888 * test 4:33f7f61e6c5e
889 889 $ hg unshelve
890 890 unshelving change 'default'
891 891 rebasing shelved changes
892 892 rebasing 5:e42a7da90865 "changes to: second" (tip)
893 893 merging a/a
894 894 warning: conflicts while merging a/a! (edit, then use 'hg resolve --mark')
895 895 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
896 896 [1]
897 897 $ hg bookmark
898 898 test 4:33f7f61e6c5e
899 899
900 900 Test that resolving all conflicts in one direction (so that the rebase
901 901 is a no-op), works (issue4398)
902 902
903 903 $ hg revert -a -r .
904 904 reverting a/a
905 905 $ hg resolve -m a/a
906 906 (no more unresolved files)
907 907 continue: hg unshelve --continue
908 908 $ hg unshelve -c
909 909 rebasing 5:e42a7da90865 "changes to: second" (tip)
910 910 note: rebase of 5:e42a7da90865 created no changes to commit
911 911 unshelve of 'default' complete
912 912 $ hg bookmark
913 913 * test 4:33f7f61e6c5e
914 914 $ hg diff
915 915 $ hg status
916 916 ? a/a.orig
917 917 ? foo/foo
918 918 $ hg summary
919 919 parent: 4:33f7f61e6c5e tip
920 920 create conflict
921 921 branch: default
922 922 bookmarks: *test
923 923 commit: 2 unknown (clean)
924 924 update: (current)
925 925 phases: 5 draft
926 926
927 927 $ hg shelve --delete --stat
928 928 abort: options '--delete' and '--stat' may not be used together
929 929 [255]
930 930 $ hg shelve --delete --name NAME
931 931 abort: options '--delete' and '--name' may not be used together
932 932 [255]
933 933
934 934 Test interactive shelve
935 935 $ cat <<EOF >> $HGRCPATH
936 936 > [ui]
937 937 > interactive = true
938 938 > EOF
939 939 $ echo 'a' >> a/b
940 940 $ cat a/a >> a/b
941 941 $ echo 'x' >> a/b
942 942 $ mv a/b a/a
943 943 $ echo 'a' >> foo/foo
944 944 $ hg st
945 945 M a/a
946 946 ? a/a.orig
947 947 ? foo/foo
948 948 $ cat a/a
949 949 a
950 950 a
951 951 c
952 952 x
953 953 x
954 954 $ cat foo/foo
955 955 foo
956 956 a
957 957 $ hg shelve --interactive --config ui.interactive=false
958 958 abort: running non-interactively
959 959 [255]
960 960 $ hg shelve --interactive << EOF
961 961 > y
962 962 > y
963 963 > n
964 964 > EOF
965 965 diff --git a/a/a b/a/a
966 966 2 hunks, 2 lines changed
967 967 examine changes to 'a/a'? [Ynesfdaq?] y
968 968
969 969 @@ -1,3 +1,4 @@
970 970 +a
971 971 a
972 972 c
973 973 x
974 974 record change 1/2 to 'a/a'? [Ynesfdaq?] y
975 975
976 976 @@ -1,3 +2,4 @@
977 977 a
978 978 c
979 979 x
980 980 +x
981 981 record change 2/2 to 'a/a'? [Ynesfdaq?] n
982 982
983 983 shelved as test
984 984 merging a/a
985 985 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
986 986 $ cat a/a
987 987 a
988 988 c
989 989 x
990 990 x
991 991 $ cat foo/foo
992 992 foo
993 993 a
994 994 $ hg st
995 995 M a/a
996 996 ? foo/foo
997 997 $ hg bookmark
998 998 * test 4:33f7f61e6c5e
999 999 $ hg unshelve
1000 1000 unshelving change 'test'
1001 1001 temporarily committing pending changes (restore with 'hg unshelve --abort')
1002 1002 rebasing shelved changes
1003 1003 rebasing 6:96a1354f65f6 "changes to: create conflict" (tip)
1004 1004 merging a/a
1005 1005 $ hg bookmark
1006 1006 * test 4:33f7f61e6c5e
1007 1007 $ cat a/a
1008 1008 a
1009 1009 a
1010 1010 c
1011 1011 x
1012 1012 x
1013 1013
1014 1014 shelve --patch and shelve --stat should work with valid shelfnames
1015 1015
1016 1016 $ hg up --clean .
1017 1017 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1018 1018 (leaving bookmark test)
1019 1019 $ hg shelve --list
1020 1020 $ echo 'patch a' > shelf-patch-a
1021 1021 $ hg add shelf-patch-a
1022 1022 $ hg shelve
1023 1023 shelved as default
1024 1024 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1025 1025 $ echo 'patch b' > shelf-patch-b
1026 1026 $ hg add shelf-patch-b
1027 1027 $ hg shelve
1028 1028 shelved as default-01
1029 1029 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1030 1030 $ hg shelve --patch default default-01
1031 1031 default-01 (*)* changes to: create conflict (glob)
1032 1032
1033 1033 diff --git a/shelf-patch-b b/shelf-patch-b
1034 1034 new file mode 100644
1035 1035 --- /dev/null
1036 1036 +++ b/shelf-patch-b
1037 1037 @@ -0,0 +1,1 @@
1038 1038 +patch b
1039 1039 default (*)* changes to: create conflict (glob)
1040 1040
1041 1041 diff --git a/shelf-patch-a b/shelf-patch-a
1042 1042 new file mode 100644
1043 1043 --- /dev/null
1044 1044 +++ b/shelf-patch-a
1045 1045 @@ -0,0 +1,1 @@
1046 1046 +patch a
1047 1047 $ hg shelve --stat default default-01
1048 1048 default-01 (*)* changes to: create conflict (glob)
1049 1049 shelf-patch-b | 1 +
1050 1050 1 files changed, 1 insertions(+), 0 deletions(-)
1051 1051 default (*)* changes to: create conflict (glob)
1052 1052 shelf-patch-a | 1 +
1053 1053 1 files changed, 1 insertions(+), 0 deletions(-)
1054 1054 $ hg shelve --patch default
1055 1055 default (*)* changes to: create conflict (glob)
1056 1056
1057 1057 diff --git a/shelf-patch-a b/shelf-patch-a
1058 1058 new file mode 100644
1059 1059 --- /dev/null
1060 1060 +++ b/shelf-patch-a
1061 1061 @@ -0,0 +1,1 @@
1062 1062 +patch a
1063 1063 $ hg shelve --stat default
1064 1064 default (*)* changes to: create conflict (glob)
1065 1065 shelf-patch-a | 1 +
1066 1066 1 files changed, 1 insertions(+), 0 deletions(-)
1067 1067 $ hg shelve --patch nonexistentshelf
1068 1068 abort: cannot find shelf nonexistentshelf
1069 1069 [255]
1070 1070 $ hg shelve --stat nonexistentshelf
1071 1071 abort: cannot find shelf nonexistentshelf
1072 1072 [255]
1073 1073 $ hg shelve --patch default nonexistentshelf
1074 1074 abort: cannot find shelf nonexistentshelf
1075 1075 [255]
1076 1076 $ hg shelve --patch
1077 1077 abort: --patch expects at least one shelf
1078 1078 [255]
1079 1079
1080 1080 $ cd ..
1081 1081
1082 1082 Shelve from general delta repo uses bundle2 on disk
1083 1083 --------------------------------------------------
1084 1084
1085 1085 no general delta
1086 1086
1087 1087 $ hg clone --pull repo bundle1 --config format.usegeneraldelta=0
1088 1088 requesting all changes
1089 1089 adding changesets
1090 1090 adding manifests
1091 1091 adding file changes
1092 1092 added 5 changesets with 8 changes to 6 files
1093 1093 new changesets cc01e2b0c59f:33f7f61e6c5e
1094 1094 updating to branch default
1095 1095 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
1096 1096 $ cd bundle1
1097 1097 $ echo babar > jungle
1098 1098 $ hg add jungle
1099 1099 $ hg shelve
1100 1100 shelved as default
1101 1101 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1102 1102 $ hg debugbundle .hg/shelved/*.hg
1103 1103 45993d65fe9dc3c6d8764b9c3b07fa831ee7d92d
1104 1104 $ cd ..
1105 1105
1106 1106 with general delta
1107 1107
1108 1108 $ hg clone --pull repo bundle2 --config format.usegeneraldelta=1
1109 1109 requesting all changes
1110 1110 adding changesets
1111 1111 adding manifests
1112 1112 adding file changes
1113 1113 added 5 changesets with 8 changes to 6 files
1114 1114 new changesets cc01e2b0c59f:33f7f61e6c5e
1115 1115 updating to branch default
1116 1116 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
1117 1117 $ cd bundle2
1118 1118 $ echo babar > jungle
1119 1119 $ hg add jungle
1120 1120 $ hg shelve
1121 1121 shelved as default
1122 1122 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1123 1123 $ hg debugbundle .hg/shelved/*.hg
1124 1124 Stream params: {Compression: BZ}
1125 changegroup -- {nbchanges: 1, version: 02}
1125 changegroup -- {nbchanges: 1, version: 02} (mandatory: True)
1126 1126 45993d65fe9dc3c6d8764b9c3b07fa831ee7d92d
1127 1127 $ cd ..
1128 1128
1129 1129 Test visibility of in-memory changes inside transaction to external hook
1130 1130 ------------------------------------------------------------------------
1131 1131
1132 1132 $ cd repo
1133 1133
1134 1134 $ echo xxxx >> x
1135 1135 $ hg commit -m "#5: changes to invoke rebase"
1136 1136
1137 1137 $ cat > $TESTTMP/checkvisibility.sh <<EOF
1138 1138 > echo "==== \$1:"
1139 1139 > hg parents --template "VISIBLE {rev}:{node|short}\n"
1140 1140 > # test that pending changes are hidden
1141 1141 > unset HG_PENDING
1142 1142 > hg parents --template "ACTUAL {rev}:{node|short}\n"
1143 1143 > echo "===="
1144 1144 > EOF
1145 1145
1146 1146 $ cat >> .hg/hgrc <<EOF
1147 1147 > [defaults]
1148 1148 > # to fix hash id of temporary revisions
1149 1149 > unshelve = --date '0 0'
1150 1150 > EOF
1151 1151
1152 1152 "hg unshelve" at REV5 implies steps below:
1153 1153
1154 1154 (1) commit changes in the working directory (REV6)
1155 1155 (2) unbundle shelved revision (REV7)
1156 1156 (3) rebase: merge REV7 into REV6 (REV6 => REV6, REV7)
1157 1157 (4) rebase: commit merged revision (REV8)
1158 1158 (5) rebase: update to REV6 (REV8 => REV6)
1159 1159 (6) update to REV5 (REV6 => REV5)
1160 1160 (7) abort transaction
1161 1161
1162 1162 == test visibility to external preupdate hook
1163 1163
1164 1164 $ cat >> .hg/hgrc <<EOF
1165 1165 > [hooks]
1166 1166 > preupdate.visibility = sh $TESTTMP/checkvisibility.sh preupdate
1167 1167 > EOF
1168 1168
1169 1169 $ echo nnnn >> n
1170 1170
1171 1171 $ sh $TESTTMP/checkvisibility.sh before-unshelving
1172 1172 ==== before-unshelving:
1173 1173 VISIBLE 5:703117a2acfb
1174 1174 ACTUAL 5:703117a2acfb
1175 1175 ====
1176 1176
1177 1177 $ hg unshelve --keep default
1178 1178 temporarily committing pending changes (restore with 'hg unshelve --abort')
1179 1179 rebasing shelved changes
1180 1180 rebasing 7:206bf5d4f922 "changes to: create conflict" (tip)
1181 1181 ==== preupdate:
1182 1182 VISIBLE 6:66b86db80ee4
1183 1183 ACTUAL 5:703117a2acfb
1184 1184 ====
1185 1185 ==== preupdate:
1186 1186 VISIBLE 8:a0e04704317e
1187 1187 ACTUAL 5:703117a2acfb
1188 1188 ====
1189 1189 ==== preupdate:
1190 1190 VISIBLE 6:66b86db80ee4
1191 1191 ACTUAL 5:703117a2acfb
1192 1192 ====
1193 1193
1194 1194 $ cat >> .hg/hgrc <<EOF
1195 1195 > [hooks]
1196 1196 > preupdate.visibility =
1197 1197 > EOF
1198 1198
1199 1199 $ sh $TESTTMP/checkvisibility.sh after-unshelving
1200 1200 ==== after-unshelving:
1201 1201 VISIBLE 5:703117a2acfb
1202 1202 ACTUAL 5:703117a2acfb
1203 1203 ====
1204 1204
1205 1205 == test visibility to external update hook
1206 1206
1207 1207 $ hg update -q -C 5
1208 1208
1209 1209 $ cat >> .hg/hgrc <<EOF
1210 1210 > [hooks]
1211 1211 > update.visibility = sh $TESTTMP/checkvisibility.sh update
1212 1212 > EOF
1213 1213
1214 1214 $ echo nnnn >> n
1215 1215
1216 1216 $ sh $TESTTMP/checkvisibility.sh before-unshelving
1217 1217 ==== before-unshelving:
1218 1218 VISIBLE 5:703117a2acfb
1219 1219 ACTUAL 5:703117a2acfb
1220 1220 ====
1221 1221
1222 1222 $ hg unshelve --keep default
1223 1223 temporarily committing pending changes (restore with 'hg unshelve --abort')
1224 1224 rebasing shelved changes
1225 1225 rebasing 7:206bf5d4f922 "changes to: create conflict" (tip)
1226 1226 ==== update:
1227 1227 VISIBLE 6:66b86db80ee4
1228 1228 VISIBLE 7:206bf5d4f922
1229 1229 ACTUAL 5:703117a2acfb
1230 1230 ====
1231 1231 ==== update:
1232 1232 VISIBLE 6:66b86db80ee4
1233 1233 ACTUAL 5:703117a2acfb
1234 1234 ====
1235 1235 ==== update:
1236 1236 VISIBLE 5:703117a2acfb
1237 1237 ACTUAL 5:703117a2acfb
1238 1238 ====
1239 1239
1240 1240 $ cat >> .hg/hgrc <<EOF
1241 1241 > [hooks]
1242 1242 > update.visibility =
1243 1243 > EOF
1244 1244
1245 1245 $ sh $TESTTMP/checkvisibility.sh after-unshelving
1246 1246 ==== after-unshelving:
1247 1247 VISIBLE 5:703117a2acfb
1248 1248 ACTUAL 5:703117a2acfb
1249 1249 ====
1250 1250
1251 1251 $ cd ..
1252 1252
1253 1253 test .orig files go where the user wants them to
1254 1254 ---------------------------------------------------------------
1255 1255 $ hg init salvage
1256 1256 $ cd salvage
1257 1257 $ echo 'content' > root
1258 1258 $ hg commit -A -m 'root' -q
1259 1259 $ echo '' > root
1260 1260 $ hg shelve -q
1261 1261 $ echo 'contADDent' > root
1262 1262 $ hg unshelve -q --config 'ui.origbackuppath=.hg/origbackups'
1263 1263 warning: conflicts while merging root! (edit, then use 'hg resolve --mark')
1264 1264 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
1265 1265 [1]
1266 1266 $ ls .hg/origbackups
1267 1267 root
1268 1268 $ rm -rf .hg/origbackups
1269 1269
1270 1270 test Abort unshelve always gets user out of the unshelved state
1271 1271 ---------------------------------------------------------------
1272 1272 Wreak havoc on the unshelve process
1273 1273 $ rm .hg/unshelverebasestate
1274 1274 $ hg unshelve --abort
1275 1275 unshelve of 'default' aborted
1276 1276 abort: $ENOENT$* (glob)
1277 1277 [255]
1278 1278 Can the user leave the current state?
1279 1279 $ hg up -C .
1280 1280 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1281 1281
1282 1282 Try again but with a corrupted shelve state file
1283 1283 $ hg strip -r 2 -r 1 -q
1284 1284 $ hg up -r 0 -q
1285 1285 $ echo '' > root
1286 1286 $ hg shelve -q
1287 1287 $ echo 'contADDent' > root
1288 1288 $ hg unshelve -q
1289 1289 warning: conflicts while merging root! (edit, then use 'hg resolve --mark')
1290 1290 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
1291 1291 [1]
1292 1292 $ sed 's/ae8c668541e8/123456789012/' .hg/shelvedstate > ../corrupt-shelvedstate
1293 1293 $ mv ../corrupt-shelvedstate .hg/histedit-state
1294 1294 $ hg unshelve --abort 2>&1 | grep 'rebase aborted'
1295 1295 rebase aborted
1296 1296 $ hg up -C .
1297 1297 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1298 1298
1299 1299 $ cd ..
1300 1300
1301 1301 Keep active bookmark while (un)shelving even on shared repo (issue4940)
1302 1302 -----------------------------------------------------------------------
1303 1303
1304 1304 $ cat <<EOF >> $HGRCPATH
1305 1305 > [extensions]
1306 1306 > share =
1307 1307 > EOF
1308 1308
1309 1309 $ hg bookmarks -R repo
1310 1310 test 4:33f7f61e6c5e
1311 1311 $ hg share -B repo share
1312 1312 updating working directory
1313 1313 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
1314 1314 $ cd share
1315 1315
1316 1316 $ hg bookmarks
1317 1317 test 4:33f7f61e6c5e
1318 1318 $ hg bookmarks foo
1319 1319 $ hg bookmarks
1320 1320 * foo 5:703117a2acfb
1321 1321 test 4:33f7f61e6c5e
1322 1322 $ echo x >> x
1323 1323 $ hg shelve
1324 1324 shelved as foo
1325 1325 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1326 1326 $ hg bookmarks
1327 1327 * foo 5:703117a2acfb
1328 1328 test 4:33f7f61e6c5e
1329 1329
1330 1330 $ hg unshelve
1331 1331 unshelving change 'foo'
1332 1332 $ hg bookmarks
1333 1333 * foo 5:703117a2acfb
1334 1334 test 4:33f7f61e6c5e
1335 1335
1336 1336 $ cd ..
1337 1337
1338 1338 Shelve and unshelve unknown files. For the purposes of unshelve, a shelved
1339 1339 unknown file is the same as a shelved added file, except that it will be in
1340 1340 unknown state after unshelve if and only if it was either absent or unknown
1341 1341 before the unshelve operation.
1342 1342
1343 1343 $ hg init unknowns
1344 1344 $ cd unknowns
1345 1345
1346 1346 The simplest case is if I simply have an unknown file that I shelve and unshelve
1347 1347
1348 1348 $ echo unknown > unknown
1349 1349 $ hg status
1350 1350 ? unknown
1351 1351 $ hg shelve --unknown
1352 1352 shelved as default
1353 1353 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1354 1354 $ hg status
1355 1355 $ hg unshelve
1356 1356 unshelving change 'default'
1357 1357 $ hg status
1358 1358 ? unknown
1359 1359 $ rm unknown
1360 1360
1361 1361 If I shelve, add the file, and unshelve, does it stay added?
1362 1362
1363 1363 $ echo unknown > unknown
1364 1364 $ hg shelve -u
1365 1365 shelved as default
1366 1366 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1367 1367 $ hg status
1368 1368 $ touch unknown
1369 1369 $ hg add unknown
1370 1370 $ hg status
1371 1371 A unknown
1372 1372 $ hg unshelve
1373 1373 unshelving change 'default'
1374 1374 temporarily committing pending changes (restore with 'hg unshelve --abort')
1375 1375 rebasing shelved changes
1376 1376 rebasing 1:098df96e7410 "(changes in empty repository)" (tip)
1377 1377 merging unknown
1378 1378 $ hg status
1379 1379 A unknown
1380 1380 $ hg forget unknown
1381 1381 $ rm unknown
1382 1382
1383 1383 And if I shelve, commit, then unshelve, does it become modified?
1384 1384
1385 1385 $ echo unknown > unknown
1386 1386 $ hg shelve -u
1387 1387 shelved as default
1388 1388 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1389 1389 $ hg status
1390 1390 $ touch unknown
1391 1391 $ hg add unknown
1392 1392 $ hg commit -qm "Add unknown"
1393 1393 $ hg status
1394 1394 $ hg unshelve
1395 1395 unshelving change 'default'
1396 1396 rebasing shelved changes
1397 1397 rebasing 1:098df96e7410 "(changes in empty repository)" (tip)
1398 1398 merging unknown
1399 1399 $ hg status
1400 1400 M unknown
1401 1401 $ hg remove --force unknown
1402 1402 $ hg commit -qm "Remove unknown"
1403 1403
1404 1404 $ cd ..
1405 1405
1406 1406 We expects that non-bare shelve keeps newly created branch in
1407 1407 working directory.
1408 1408
1409 1409 $ hg init shelve-preserve-new-branch
1410 1410 $ cd shelve-preserve-new-branch
1411 1411 $ echo "a" >> a
1412 1412 $ hg add a
1413 1413 $ echo "b" >> b
1414 1414 $ hg add b
1415 1415 $ hg commit -m "ab"
1416 1416 $ echo "aa" >> a
1417 1417 $ echo "bb" >> b
1418 1418 $ hg branch new-branch
1419 1419 marked working directory as branch new-branch
1420 1420 (branches are permanent and global, did you want a bookmark?)
1421 1421 $ hg status
1422 1422 M a
1423 1423 M b
1424 1424 $ hg branch
1425 1425 new-branch
1426 1426 $ hg shelve a
1427 1427 shelved as default
1428 1428 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1429 1429 $ hg branch
1430 1430 new-branch
1431 1431 $ hg status
1432 1432 M b
1433 1433 $ touch "c" >> c
1434 1434 $ hg add c
1435 1435 $ hg status
1436 1436 M b
1437 1437 A c
1438 1438 $ hg shelve --exclude c
1439 1439 shelved as default-01
1440 1440 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1441 1441 $ hg branch
1442 1442 new-branch
1443 1443 $ hg status
1444 1444 A c
1445 1445 $ hg shelve --include c
1446 1446 shelved as default-02
1447 1447 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1448 1448 $ hg branch
1449 1449 new-branch
1450 1450 $ hg status
1451 1451 $ echo "d" >> d
1452 1452 $ hg add d
1453 1453 $ hg status
1454 1454 A d
1455 1455
1456 1456 We expect that bare-shelve will not keep branch in current working directory.
1457 1457
1458 1458 $ hg shelve
1459 1459 shelved as default-03
1460 1460 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1461 1461 $ hg branch
1462 1462 default
1463 1463 $ cd ..
1464 1464
1465 1465 When i shelve commit on newly created branch i expect
1466 1466 that after unshelve newly created branch will be preserved.
1467 1467
1468 1468 $ hg init shelve_on_new_branch_simple
1469 1469 $ cd shelve_on_new_branch_simple
1470 1470 $ echo "aaa" >> a
1471 1471 $ hg commit -A -m "a"
1472 1472 adding a
1473 1473 $ hg branch
1474 1474 default
1475 1475 $ hg branch test
1476 1476 marked working directory as branch test
1477 1477 (branches are permanent and global, did you want a bookmark?)
1478 1478 $ echo "bbb" >> a
1479 1479 $ hg status
1480 1480 M a
1481 1481 $ hg shelve
1482 1482 shelved as default
1483 1483 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1484 1484 $ hg branch
1485 1485 default
1486 1486 $ echo "bbb" >> b
1487 1487 $ hg status
1488 1488 ? b
1489 1489 $ hg unshelve
1490 1490 unshelving change 'default'
1491 1491 marked working directory as branch test
1492 1492 $ hg status
1493 1493 M a
1494 1494 ? b
1495 1495 $ hg branch
1496 1496 test
1497 1497 $ cd ..
1498 1498
1499 1499 When i shelve commit on newly created branch, make
1500 1500 some changes, unshelve it and running into merge
1501 1501 conflicts i expect that after fixing them and
1502 1502 running unshelve --continue newly created branch
1503 1503 will be preserved.
1504 1504
1505 1505 $ hg init shelve_on_new_branch_conflict
1506 1506 $ cd shelve_on_new_branch_conflict
1507 1507 $ echo "aaa" >> a
1508 1508 $ hg commit -A -m "a"
1509 1509 adding a
1510 1510 $ hg branch
1511 1511 default
1512 1512 $ hg branch test
1513 1513 marked working directory as branch test
1514 1514 (branches are permanent and global, did you want a bookmark?)
1515 1515 $ echo "bbb" >> a
1516 1516 $ hg status
1517 1517 M a
1518 1518 $ hg shelve
1519 1519 shelved as default
1520 1520 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1521 1521 $ hg branch
1522 1522 default
1523 1523 $ echo "ccc" >> a
1524 1524 $ hg status
1525 1525 M a
1526 1526 $ hg unshelve
1527 1527 unshelving change 'default'
1528 1528 temporarily committing pending changes (restore with 'hg unshelve --abort')
1529 1529 rebasing shelved changes
1530 1530 rebasing 2:425c97ef07f3 "changes to: a" (tip)
1531 1531 merging a
1532 1532 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
1533 1533 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
1534 1534 [1]
1535 1535 $ echo "aaabbbccc" > a
1536 1536 $ rm a.orig
1537 1537 $ hg resolve --mark a
1538 1538 (no more unresolved files)
1539 1539 continue: hg unshelve --continue
1540 1540 $ hg unshelve --continue
1541 1541 rebasing 2:425c97ef07f3 "changes to: a" (tip)
1542 1542 marked working directory as branch test
1543 1543 unshelve of 'default' complete
1544 1544 $ cat a
1545 1545 aaabbbccc
1546 1546 $ hg status
1547 1547 M a
1548 1548 $ hg branch
1549 1549 test
1550 1550 $ hg commit -m "test-commit"
1551 1551
1552 1552 When i shelve on test branch, update to default branch
1553 1553 and unshelve i expect that it will not preserve previous
1554 1554 test branch.
1555 1555
1556 1556 $ echo "xxx" > b
1557 1557 $ hg add b
1558 1558 $ hg shelve
1559 1559 shelved as test
1560 1560 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1561 1561 $ hg update -r default
1562 1562 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1563 1563 $ hg unshelve
1564 1564 unshelving change 'test'
1565 1565 rebasing shelved changes
1566 1566 rebasing 2:357525f34729 "changes to: test-commit" (tip)
1567 1567 $ hg status
1568 1568 A b
1569 1569 $ hg branch
1570 1570 default
1571 1571 $ cd ..
1572 1572
1573 1573 When i unshelve resulting in merge conflicts and makes saved
1574 1574 file shelvedstate looks like in previous versions in
1575 1575 mercurial(without restore branch information in 7th line) i
1576 1576 expect that after resolving conflicts and successfully
1577 1577 running 'shelve --continue' the branch information won't be
1578 1578 restored and branch will be unchanged.
1579 1579
1580 1580 shelve on new branch, conflict with previous shelvedstate
1581 1581
1582 1582 $ hg init conflict
1583 1583 $ cd conflict
1584 1584 $ echo "aaa" >> a
1585 1585 $ hg commit -A -m "a"
1586 1586 adding a
1587 1587 $ hg branch
1588 1588 default
1589 1589 $ hg branch test
1590 1590 marked working directory as branch test
1591 1591 (branches are permanent and global, did you want a bookmark?)
1592 1592 $ echo "bbb" >> a
1593 1593 $ hg status
1594 1594 M a
1595 1595 $ hg shelve
1596 1596 shelved as default
1597 1597 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1598 1598 $ hg branch
1599 1599 default
1600 1600 $ echo "ccc" >> a
1601 1601 $ hg status
1602 1602 M a
1603 1603 $ hg unshelve
1604 1604 unshelving change 'default'
1605 1605 temporarily committing pending changes (restore with 'hg unshelve --abort')
1606 1606 rebasing shelved changes
1607 1607 rebasing 2:425c97ef07f3 "changes to: a" (tip)
1608 1608 merging a
1609 1609 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
1610 1610 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
1611 1611 [1]
1612 1612
1613 1613 Removing restore branch information from shelvedstate file(making it looks like
1614 1614 in previous versions) and running unshelve --continue
1615 1615
1616 1616 $ cp .hg/shelvedstate .hg/shelvedstate_old
1617 1617 $ cat .hg/shelvedstate_old | grep -v 'branchtorestore' > .hg/shelvedstate
1618 1618
1619 1619 $ echo "aaabbbccc" > a
1620 1620 $ rm a.orig
1621 1621 $ hg resolve --mark a
1622 1622 (no more unresolved files)
1623 1623 continue: hg unshelve --continue
1624 1624 $ hg unshelve --continue
1625 1625 rebasing 2:425c97ef07f3 "changes to: a" (tip)
1626 1626 unshelve of 'default' complete
1627 1627 $ cat a
1628 1628 aaabbbccc
1629 1629 $ hg status
1630 1630 M a
1631 1631 $ hg branch
1632 1632 default
1633 1633 $ cd ..
1634 1634
1635 1635 On non bare shelve the branch information shouldn't be restored
1636 1636
1637 1637 $ hg init bare_shelve_on_new_branch
1638 1638 $ cd bare_shelve_on_new_branch
1639 1639 $ echo "aaa" >> a
1640 1640 $ hg commit -A -m "a"
1641 1641 adding a
1642 1642 $ hg branch
1643 1643 default
1644 1644 $ hg branch test
1645 1645 marked working directory as branch test
1646 1646 (branches are permanent and global, did you want a bookmark?)
1647 1647 $ echo "bbb" >> a
1648 1648 $ hg status
1649 1649 M a
1650 1650 $ hg shelve a
1651 1651 shelved as default
1652 1652 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1653 1653 $ hg branch
1654 1654 test
1655 1655 $ hg branch default
1656 1656 marked working directory as branch default
1657 1657 (branches are permanent and global, did you want a bookmark?)
1658 1658 $ echo "bbb" >> b
1659 1659 $ hg status
1660 1660 ? b
1661 1661 $ hg unshelve
1662 1662 unshelving change 'default'
1663 1663 $ hg status
1664 1664 M a
1665 1665 ? b
1666 1666 $ hg branch
1667 1667 default
1668 1668 $ cd ..
1669 1669
1670 1670 Prepare unshelve with a corrupted shelvedstate
1671 1671 $ hg init r1 && cd r1
1672 1672 $ echo text1 > file && hg add file
1673 1673 $ hg shelve
1674 1674 shelved as default
1675 1675 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1676 1676 $ echo text2 > file && hg ci -Am text1
1677 1677 adding file
1678 1678 $ hg unshelve
1679 1679 unshelving change 'default'
1680 1680 rebasing shelved changes
1681 1681 rebasing 1:396ea74229f9 "(changes in empty repository)" (tip)
1682 1682 merging file
1683 1683 warning: conflicts while merging file! (edit, then use 'hg resolve --mark')
1684 1684 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
1685 1685 [1]
1686 1686 $ echo somethingsomething > .hg/shelvedstate
1687 1687
1688 1688 Unshelve --continue fails with appropriate message if shelvedstate is corrupted
1689 1689 $ hg unshelve --continue
1690 1690 abort: corrupted shelved state file
1691 1691 (please run hg unshelve --abort to abort unshelve operation)
1692 1692 [255]
1693 1693
1694 1694 Unshelve --abort works with a corrupted shelvedstate
1695 1695 $ hg unshelve --abort
1696 1696 could not read shelved state file, your working copy may be in an unexpected state
1697 1697 please update to some commit
1698 1698
1699 1699 Unshelve --abort fails with appropriate message if there's no unshelve in
1700 1700 progress
1701 1701 $ hg unshelve --abort
1702 1702 abort: no unshelve in progress
1703 1703 [255]
1704 1704 $ cd ..
1705 1705
1706 1706 Unshelve respects --keep even if user intervention is needed
1707 1707 $ hg init unshelvekeep && cd unshelvekeep
1708 1708 $ echo 1 > file && hg ci -Am 1
1709 1709 adding file
1710 1710 $ echo 2 >> file
1711 1711 $ hg shelve
1712 1712 shelved as default
1713 1713 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1714 1714 $ echo 3 >> file && hg ci -Am 13
1715 1715 $ hg shelve --list
1716 1716 default (*s ago) * changes to: 1 (glob)
1717 1717 $ hg unshelve --keep
1718 1718 unshelving change 'default'
1719 1719 rebasing shelved changes
1720 1720 rebasing 2:3fbe6fbb0bef "changes to: 1" (tip)
1721 1721 merging file
1722 1722 warning: conflicts while merging file! (edit, then use 'hg resolve --mark')
1723 1723 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
1724 1724 [1]
1725 1725 $ hg resolve --mark file
1726 1726 (no more unresolved files)
1727 1727 continue: hg unshelve --continue
1728 1728 $ hg unshelve --continue
1729 1729 rebasing 2:3fbe6fbb0bef "changes to: 1" (tip)
1730 1730 unshelve of 'default' complete
1731 1731 $ hg shelve --list
1732 1732 default (*s ago) * changes to: 1 (glob)
1733 1733 $ cd ..
1734 1734
1735 1735 Unshelving when there are deleted files does not crash (issue4176)
1736 1736 $ hg init unshelve-deleted-file && cd unshelve-deleted-file
1737 1737 $ echo a > a && echo b > b && hg ci -Am ab
1738 1738 adding a
1739 1739 adding b
1740 1740 $ echo aa > a && hg shelve
1741 1741 shelved as default
1742 1742 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1743 1743 $ rm b
1744 1744 $ hg st
1745 1745 ! b
1746 1746 $ hg unshelve
1747 1747 unshelving change 'default'
1748 1748 $ hg shelve
1749 1749 shelved as default
1750 1750 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1751 1751 $ rm a && echo b > b
1752 1752 $ hg st
1753 1753 ! a
1754 1754 $ hg unshelve
1755 1755 unshelving change 'default'
1756 1756 abort: shelved change touches missing files
1757 1757 (run hg status to see which files are missing)
1758 1758 [255]
1759 1759 $ hg st
1760 1760 ! a
1761 1761 $ cd ..
1762 1762
1763 1763 New versions of Mercurial know how to read onld shelvedstate files
1764 1764 $ hg init oldshelvedstate
1765 1765 $ cd oldshelvedstate
1766 1766 $ echo root > root && hg ci -Am root
1767 1767 adding root
1768 1768 $ echo 1 > a
1769 1769 $ hg add a
1770 1770 $ hg shelve --name ashelve
1771 1771 shelved as ashelve
1772 1772 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1773 1773 $ echo 2 > a
1774 1774 $ hg ci -Am a
1775 1775 adding a
1776 1776 $ hg unshelve
1777 1777 unshelving change 'ashelve'
1778 1778 rebasing shelved changes
1779 1779 rebasing 2:003d2d94241c "changes to: root" (tip)
1780 1780 merging a
1781 1781 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
1782 1782 unresolved conflicts (see 'hg resolve', then 'hg unshelve --continue')
1783 1783 [1]
1784 1784 putting v1 shelvedstate file in place of a created v2
1785 1785 $ cat << EOF > .hg/shelvedstate
1786 1786 > 1
1787 1787 > ashelve
1788 1788 > 8b058dae057a5a78f393f4535d9e363dd5efac9d
1789 1789 > 8b058dae057a5a78f393f4535d9e363dd5efac9d
1790 1790 > 8b058dae057a5a78f393f4535d9e363dd5efac9d 003d2d94241cc7aff0c3a148e966d6a4a377f3a7
1791 1791 > 003d2d94241cc7aff0c3a148e966d6a4a377f3a7
1792 1792 >
1793 1793 > nokeep
1794 1794 > :no-active-bookmark
1795 1795 > EOF
1796 1796 $ echo 1 > a
1797 1797 $ hg resolve --mark a
1798 1798 (no more unresolved files)
1799 1799 continue: hg unshelve --continue
1800 1800 mercurial does not crash
1801 1801 $ hg unshelve --continue
1802 1802 rebasing 2:003d2d94241c "changes to: root" (tip)
1803 1803 unshelve of 'ashelve' complete
1804 1804 $ cd ..
1805 1805
@@ -1,172 +1,172 b''
1 1 #require no-reposimplestore
2 2
3 3 Test creating a consuming stream bundle v2
4 4
5 5 $ getmainid() {
6 6 > hg -R main log --template '{node}\n' --rev "$1"
7 7 > }
8 8
9 9 $ cp $HGRCPATH $TESTTMP/hgrc.orig
10 10
11 11 $ cat >> $HGRCPATH << EOF
12 12 > [experimental]
13 13 > evolution.createmarkers=True
14 14 > evolution.exchange=True
15 15 > bundle2-output-capture=True
16 16 > [ui]
17 17 > ssh="$PYTHON" "$TESTDIR/dummyssh"
18 18 > logtemplate={rev}:{node|short} {phase} {author} {bookmarks} {desc|firstline}
19 19 > [web]
20 20 > push_ssl = false
21 21 > allow_push = *
22 22 > [phases]
23 23 > publish=False
24 24 > [extensions]
25 25 > drawdag=$TESTDIR/drawdag.py
26 26 > clonebundles=
27 27 > EOF
28 28
29 29 The extension requires a repo (currently unused)
30 30
31 31 $ hg init main
32 32 $ cd main
33 33
34 34 $ hg debugdrawdag <<'EOF'
35 35 > E
36 36 > |
37 37 > D
38 38 > |
39 39 > C
40 40 > |
41 41 > B
42 42 > |
43 43 > A
44 44 > EOF
45 45
46 46 $ hg bundle -a --type="none-v2;stream=v2" bundle.hg
47 47 $ hg debugbundle bundle.hg
48 48 Stream params: {}
49 stream2 -- {bytecount: 1693, filecount: 11, requirements: dotencode%2Cfncache%2Cgeneraldelta%2Crevlogv1%2Cstore}
49 stream2 -- {bytecount: 1693, filecount: 11, requirements: dotencode%2Cfncache%2Cgeneraldelta%2Crevlogv1%2Cstore} (mandatory: True)
50 50 $ hg debugbundle --spec bundle.hg
51 51 none-v2;stream=v2;requirements%3Ddotencode%2Cfncache%2Cgeneraldelta%2Crevlogv1%2Cstore
52 52
53 53 Test that we can apply the bundle as a stream clone bundle
54 54
55 55 $ cat > .hg/clonebundles.manifest << EOF
56 56 > http://localhost:$HGPORT1/bundle.hg BUNDLESPEC=`hg debugbundle --spec bundle.hg`
57 57 > EOF
58 58
59 59 $ hg serve -d -p $HGPORT --pid-file hg.pid --accesslog access.log
60 60 $ cat hg.pid >> $DAEMON_PIDS
61 61
62 62 $ "$PYTHON" $TESTDIR/dumbhttp.py -p $HGPORT1 --pid http.pid
63 63 $ cat http.pid >> $DAEMON_PIDS
64 64
65 65 $ cd ..
66 66 $ hg clone http://localhost:$HGPORT streamv2-clone-implicit --debug
67 67 using http://localhost:$HGPORT/
68 68 sending capabilities command
69 69 sending clonebundles command
70 70 applying clone bundle from http://localhost:$HGPORT1/bundle.hg
71 71 bundle2-input-bundle: with-transaction
72 72 bundle2-input-part: "stream2" (params: 3 mandatory) supported
73 73 applying stream bundle
74 74 11 files to transfer, 1.65 KB of data
75 75 starting 4 threads for background file closing (?)
76 76 starting 4 threads for background file closing (?)
77 77 adding [s] data/A.i (66 bytes)
78 78 adding [s] data/B.i (66 bytes)
79 79 adding [s] data/C.i (66 bytes)
80 80 adding [s] data/D.i (66 bytes)
81 81 adding [s] data/E.i (66 bytes)
82 82 adding [s] 00manifest.i (584 bytes)
83 83 adding [s] 00changelog.i (595 bytes)
84 84 adding [s] phaseroots (43 bytes)
85 85 adding [c] branch2-served (94 bytes)
86 86 adding [c] rbc-names-v1 (7 bytes)
87 87 adding [c] rbc-revs-v1 (40 bytes)
88 88 transferred 1.65 KB in \d\.\d seconds \(.*/sec\) (re)
89 89 bundle2-input-part: total payload size 1840
90 90 bundle2-input-bundle: 0 parts total
91 91 finished applying clone bundle
92 92 query 1; heads
93 93 sending batch command
94 94 searching for changes
95 95 all remote heads known locally
96 96 no changes found
97 97 sending getbundle command
98 98 bundle2-input-bundle: with-transaction
99 99 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
100 100 bundle2-input-part: "phase-heads" supported
101 101 bundle2-input-part: total payload size 24
102 102 bundle2-input-bundle: 1 parts total
103 103 checking for updated bookmarks
104 104 updating to branch default
105 105 resolving manifests
106 106 branchmerge: False, force: False, partial: False
107 107 ancestor: 000000000000, local: 000000000000+, remote: 9bc730a19041
108 108 A: remote created -> g
109 109 getting A
110 110 B: remote created -> g
111 111 getting B
112 112 C: remote created -> g
113 113 getting C
114 114 D: remote created -> g
115 115 getting D
116 116 E: remote created -> g
117 117 getting E
118 118 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
119 119
120 120 $ hg clone --stream http://localhost:$HGPORT streamv2-clone-explicit --debug
121 121 using http://localhost:$HGPORT/
122 122 sending capabilities command
123 123 sending clonebundles command
124 124 applying clone bundle from http://localhost:$HGPORT1/bundle.hg
125 125 bundle2-input-bundle: with-transaction
126 126 bundle2-input-part: "stream2" (params: 3 mandatory) supported
127 127 applying stream bundle
128 128 11 files to transfer, 1.65 KB of data
129 129 starting 4 threads for background file closing (?)
130 130 starting 4 threads for background file closing (?)
131 131 adding [s] data/A.i (66 bytes)
132 132 adding [s] data/B.i (66 bytes)
133 133 adding [s] data/C.i (66 bytes)
134 134 adding [s] data/D.i (66 bytes)
135 135 adding [s] data/E.i (66 bytes)
136 136 adding [s] 00manifest.i (584 bytes)
137 137 adding [s] 00changelog.i (595 bytes)
138 138 adding [s] phaseroots (43 bytes)
139 139 adding [c] branch2-served (94 bytes)
140 140 adding [c] rbc-names-v1 (7 bytes)
141 141 adding [c] rbc-revs-v1 (40 bytes)
142 142 transferred 1.65 KB in *.* seconds (*/sec) (glob)
143 143 bundle2-input-part: total payload size 1840
144 144 bundle2-input-bundle: 0 parts total
145 145 finished applying clone bundle
146 146 query 1; heads
147 147 sending batch command
148 148 searching for changes
149 149 all remote heads known locally
150 150 no changes found
151 151 sending getbundle command
152 152 bundle2-input-bundle: with-transaction
153 153 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
154 154 bundle2-input-part: "phase-heads" supported
155 155 bundle2-input-part: total payload size 24
156 156 bundle2-input-bundle: 1 parts total
157 157 checking for updated bookmarks
158 158 updating to branch default
159 159 resolving manifests
160 160 branchmerge: False, force: False, partial: False
161 161 ancestor: 000000000000, local: 000000000000+, remote: 9bc730a19041
162 162 A: remote created -> g
163 163 getting A
164 164 B: remote created -> g
165 165 getting B
166 166 C: remote created -> g
167 167 getting C
168 168 D: remote created -> g
169 169 getting D
170 170 E: remote created -> g
171 171 getting E
172 172 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
@@ -1,1348 +1,1348 b''
1 1 $ echo "[extensions]" >> $HGRCPATH
2 2 $ echo "strip=" >> $HGRCPATH
3 3 $ echo "drawdag=$TESTDIR/drawdag.py" >> $HGRCPATH
4 4
5 5 $ restore() {
6 6 > hg unbundle -q .hg/strip-backup/*
7 7 > rm .hg/strip-backup/*
8 8 > }
9 9 $ teststrip() {
10 10 > hg up -C $1
11 11 > echo % before update $1, strip $2
12 12 > hg parents
13 13 > hg --traceback strip $2
14 14 > echo % after update $1, strip $2
15 15 > hg parents
16 16 > restore
17 17 > }
18 18
19 19 $ hg init test
20 20 $ cd test
21 21
22 22 $ echo foo > bar
23 23 $ hg ci -Ama
24 24 adding bar
25 25
26 26 $ echo more >> bar
27 27 $ hg ci -Amb
28 28
29 29 $ echo blah >> bar
30 30 $ hg ci -Amc
31 31
32 32 $ hg up 1
33 33 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
34 34 $ echo blah >> bar
35 35 $ hg ci -Amd
36 36 created new head
37 37
38 38 $ echo final >> bar
39 39 $ hg ci -Ame
40 40
41 41 $ hg log
42 42 changeset: 4:443431ffac4f
43 43 tag: tip
44 44 user: test
45 45 date: Thu Jan 01 00:00:00 1970 +0000
46 46 summary: e
47 47
48 48 changeset: 3:65bd5f99a4a3
49 49 parent: 1:ef3a871183d7
50 50 user: test
51 51 date: Thu Jan 01 00:00:00 1970 +0000
52 52 summary: d
53 53
54 54 changeset: 2:264128213d29
55 55 user: test
56 56 date: Thu Jan 01 00:00:00 1970 +0000
57 57 summary: c
58 58
59 59 changeset: 1:ef3a871183d7
60 60 user: test
61 61 date: Thu Jan 01 00:00:00 1970 +0000
62 62 summary: b
63 63
64 64 changeset: 0:9ab35a2d17cb
65 65 user: test
66 66 date: Thu Jan 01 00:00:00 1970 +0000
67 67 summary: a
68 68
69 69
70 70 $ teststrip 4 4
71 71 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
72 72 % before update 4, strip 4
73 73 changeset: 4:443431ffac4f
74 74 tag: tip
75 75 user: test
76 76 date: Thu Jan 01 00:00:00 1970 +0000
77 77 summary: e
78 78
79 79 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
80 80 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
81 81 % after update 4, strip 4
82 82 changeset: 3:65bd5f99a4a3
83 83 tag: tip
84 84 parent: 1:ef3a871183d7
85 85 user: test
86 86 date: Thu Jan 01 00:00:00 1970 +0000
87 87 summary: d
88 88
89 89 $ teststrip 4 3
90 90 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
91 91 % before update 4, strip 3
92 92 changeset: 4:443431ffac4f
93 93 tag: tip
94 94 user: test
95 95 date: Thu Jan 01 00:00:00 1970 +0000
96 96 summary: e
97 97
98 98 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
99 99 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
100 100 % after update 4, strip 3
101 101 changeset: 1:ef3a871183d7
102 102 user: test
103 103 date: Thu Jan 01 00:00:00 1970 +0000
104 104 summary: b
105 105
106 106 $ teststrip 1 4
107 107 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
108 108 % before update 1, strip 4
109 109 changeset: 1:ef3a871183d7
110 110 user: test
111 111 date: Thu Jan 01 00:00:00 1970 +0000
112 112 summary: b
113 113
114 114 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
115 115 % after update 1, strip 4
116 116 changeset: 1:ef3a871183d7
117 117 user: test
118 118 date: Thu Jan 01 00:00:00 1970 +0000
119 119 summary: b
120 120
121 121 $ teststrip 4 2
122 122 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
123 123 % before update 4, strip 2
124 124 changeset: 4:443431ffac4f
125 125 tag: tip
126 126 user: test
127 127 date: Thu Jan 01 00:00:00 1970 +0000
128 128 summary: e
129 129
130 130 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
131 131 % after update 4, strip 2
132 132 changeset: 3:443431ffac4f
133 133 tag: tip
134 134 user: test
135 135 date: Thu Jan 01 00:00:00 1970 +0000
136 136 summary: e
137 137
138 138 $ teststrip 4 1
139 139 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
140 140 % before update 4, strip 1
141 141 changeset: 4:264128213d29
142 142 tag: tip
143 143 parent: 1:ef3a871183d7
144 144 user: test
145 145 date: Thu Jan 01 00:00:00 1970 +0000
146 146 summary: c
147 147
148 148 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
149 149 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
150 150 % after update 4, strip 1
151 151 changeset: 0:9ab35a2d17cb
152 152 tag: tip
153 153 user: test
154 154 date: Thu Jan 01 00:00:00 1970 +0000
155 155 summary: a
156 156
157 157 $ teststrip null 4
158 158 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
159 159 % before update null, strip 4
160 160 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
161 161 % after update null, strip 4
162 162
163 163 $ hg log
164 164 changeset: 4:264128213d29
165 165 tag: tip
166 166 parent: 1:ef3a871183d7
167 167 user: test
168 168 date: Thu Jan 01 00:00:00 1970 +0000
169 169 summary: c
170 170
171 171 changeset: 3:443431ffac4f
172 172 user: test
173 173 date: Thu Jan 01 00:00:00 1970 +0000
174 174 summary: e
175 175
176 176 changeset: 2:65bd5f99a4a3
177 177 user: test
178 178 date: Thu Jan 01 00:00:00 1970 +0000
179 179 summary: d
180 180
181 181 changeset: 1:ef3a871183d7
182 182 user: test
183 183 date: Thu Jan 01 00:00:00 1970 +0000
184 184 summary: b
185 185
186 186 changeset: 0:9ab35a2d17cb
187 187 user: test
188 188 date: Thu Jan 01 00:00:00 1970 +0000
189 189 summary: a
190 190
191 191 $ hg up -C 4
192 192 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
193 193 $ hg parents
194 194 changeset: 4:264128213d29
195 195 tag: tip
196 196 parent: 1:ef3a871183d7
197 197 user: test
198 198 date: Thu Jan 01 00:00:00 1970 +0000
199 199 summary: c
200 200
201 201
202 202 $ hg --traceback strip 4
203 203 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
204 204 saved backup bundle to $TESTTMP/test/.hg/strip-backup/264128213d29-0b39d6bf-backup.hg
205 205 $ hg parents
206 206 changeset: 1:ef3a871183d7
207 207 user: test
208 208 date: Thu Jan 01 00:00:00 1970 +0000
209 209 summary: b
210 210
211 211 $ hg debugbundle .hg/strip-backup/*
212 212 Stream params: {Compression: BZ}
213 changegroup -- {nbchanges: 1, version: 02}
213 changegroup -- {nbchanges: 1, version: 02} (mandatory: True)
214 214 264128213d290d868c54642d13aeaa3675551a78
215 cache:rev-branch-cache -- {}
216 phase-heads -- {}
215 cache:rev-branch-cache -- {} (mandatory: True)
216 phase-heads -- {} (mandatory: True)
217 217 264128213d290d868c54642d13aeaa3675551a78 draft
218 218 $ hg unbundle .hg/strip-backup/*
219 219 adding changesets
220 220 adding manifests
221 221 adding file changes
222 222 added 1 changesets with 0 changes to 1 files (+1 heads)
223 223 new changesets 264128213d29
224 224 (run 'hg heads' to see heads, 'hg merge' to merge)
225 225 $ rm .hg/strip-backup/*
226 226 $ hg log --graph
227 227 o changeset: 4:264128213d29
228 228 | tag: tip
229 229 | parent: 1:ef3a871183d7
230 230 | user: test
231 231 | date: Thu Jan 01 00:00:00 1970 +0000
232 232 | summary: c
233 233 |
234 234 | o changeset: 3:443431ffac4f
235 235 | | user: test
236 236 | | date: Thu Jan 01 00:00:00 1970 +0000
237 237 | | summary: e
238 238 | |
239 239 | o changeset: 2:65bd5f99a4a3
240 240 |/ user: test
241 241 | date: Thu Jan 01 00:00:00 1970 +0000
242 242 | summary: d
243 243 |
244 244 @ changeset: 1:ef3a871183d7
245 245 | user: test
246 246 | date: Thu Jan 01 00:00:00 1970 +0000
247 247 | summary: b
248 248 |
249 249 o changeset: 0:9ab35a2d17cb
250 250 user: test
251 251 date: Thu Jan 01 00:00:00 1970 +0000
252 252 summary: a
253 253
254 254 $ hg up -C 2
255 255 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
256 256 $ hg merge 4
257 257 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
258 258 (branch merge, don't forget to commit)
259 259
260 260 before strip of merge parent
261 261
262 262 $ hg parents
263 263 changeset: 2:65bd5f99a4a3
264 264 user: test
265 265 date: Thu Jan 01 00:00:00 1970 +0000
266 266 summary: d
267 267
268 268 changeset: 4:264128213d29
269 269 tag: tip
270 270 parent: 1:ef3a871183d7
271 271 user: test
272 272 date: Thu Jan 01 00:00:00 1970 +0000
273 273 summary: c
274 274
275 275 $ hg strip 4
276 276 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
277 277 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
278 278
279 279 after strip of merge parent
280 280
281 281 $ hg parents
282 282 changeset: 1:ef3a871183d7
283 283 user: test
284 284 date: Thu Jan 01 00:00:00 1970 +0000
285 285 summary: b
286 286
287 287 $ restore
288 288
289 289 $ hg up
290 290 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
291 291 updated to "264128213d29: c"
292 292 1 other heads for branch "default"
293 293 $ hg log -G
294 294 @ changeset: 4:264128213d29
295 295 | tag: tip
296 296 | parent: 1:ef3a871183d7
297 297 | user: test
298 298 | date: Thu Jan 01 00:00:00 1970 +0000
299 299 | summary: c
300 300 |
301 301 | o changeset: 3:443431ffac4f
302 302 | | user: test
303 303 | | date: Thu Jan 01 00:00:00 1970 +0000
304 304 | | summary: e
305 305 | |
306 306 | o changeset: 2:65bd5f99a4a3
307 307 |/ user: test
308 308 | date: Thu Jan 01 00:00:00 1970 +0000
309 309 | summary: d
310 310 |
311 311 o changeset: 1:ef3a871183d7
312 312 | user: test
313 313 | date: Thu Jan 01 00:00:00 1970 +0000
314 314 | summary: b
315 315 |
316 316 o changeset: 0:9ab35a2d17cb
317 317 user: test
318 318 date: Thu Jan 01 00:00:00 1970 +0000
319 319 summary: a
320 320
321 321
322 322 2 is parent of 3, only one strip should happen
323 323
324 324 $ hg strip "roots(2)" 3
325 325 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
326 326 $ hg log -G
327 327 @ changeset: 2:264128213d29
328 328 | tag: tip
329 329 | user: test
330 330 | date: Thu Jan 01 00:00:00 1970 +0000
331 331 | summary: c
332 332 |
333 333 o changeset: 1:ef3a871183d7
334 334 | user: test
335 335 | date: Thu Jan 01 00:00:00 1970 +0000
336 336 | summary: b
337 337 |
338 338 o changeset: 0:9ab35a2d17cb
339 339 user: test
340 340 date: Thu Jan 01 00:00:00 1970 +0000
341 341 summary: a
342 342
343 343 $ restore
344 344 $ hg log -G
345 345 o changeset: 4:443431ffac4f
346 346 | tag: tip
347 347 | user: test
348 348 | date: Thu Jan 01 00:00:00 1970 +0000
349 349 | summary: e
350 350 |
351 351 o changeset: 3:65bd5f99a4a3
352 352 | parent: 1:ef3a871183d7
353 353 | user: test
354 354 | date: Thu Jan 01 00:00:00 1970 +0000
355 355 | summary: d
356 356 |
357 357 | @ changeset: 2:264128213d29
358 358 |/ user: test
359 359 | date: Thu Jan 01 00:00:00 1970 +0000
360 360 | summary: c
361 361 |
362 362 o changeset: 1:ef3a871183d7
363 363 | user: test
364 364 | date: Thu Jan 01 00:00:00 1970 +0000
365 365 | summary: b
366 366 |
367 367 o changeset: 0:9ab35a2d17cb
368 368 user: test
369 369 date: Thu Jan 01 00:00:00 1970 +0000
370 370 summary: a
371 371
372 372 Failed hook while applying "saveheads" bundle.
373 373
374 374 $ hg strip 2 --config hooks.pretxnchangegroup.bad=false
375 375 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
376 376 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
377 377 transaction abort!
378 378 rollback completed
379 379 strip failed, backup bundle stored in '$TESTTMP/test/.hg/strip-backup/*-backup.hg' (glob)
380 380 strip failed, unrecovered changes stored in '$TESTTMP/test/.hg/strip-backup/*-temp.hg' (glob)
381 381 (fix the problem, then recover the changesets with "hg unbundle '$TESTTMP/test/.hg/strip-backup/*-temp.hg'") (glob)
382 382 abort: pretxnchangegroup.bad hook exited with status 1
383 383 [255]
384 384 $ restore
385 385 $ hg log -G
386 386 o changeset: 4:443431ffac4f
387 387 | tag: tip
388 388 | user: test
389 389 | date: Thu Jan 01 00:00:00 1970 +0000
390 390 | summary: e
391 391 |
392 392 o changeset: 3:65bd5f99a4a3
393 393 | parent: 1:ef3a871183d7
394 394 | user: test
395 395 | date: Thu Jan 01 00:00:00 1970 +0000
396 396 | summary: d
397 397 |
398 398 | o changeset: 2:264128213d29
399 399 |/ user: test
400 400 | date: Thu Jan 01 00:00:00 1970 +0000
401 401 | summary: c
402 402 |
403 403 @ changeset: 1:ef3a871183d7
404 404 | user: test
405 405 | date: Thu Jan 01 00:00:00 1970 +0000
406 406 | summary: b
407 407 |
408 408 o changeset: 0:9ab35a2d17cb
409 409 user: test
410 410 date: Thu Jan 01 00:00:00 1970 +0000
411 411 summary: a
412 412
413 413
414 414 2 different branches: 2 strips
415 415
416 416 $ hg strip 2 4
417 417 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
418 418 $ hg log -G
419 419 o changeset: 2:65bd5f99a4a3
420 420 | tag: tip
421 421 | user: test
422 422 | date: Thu Jan 01 00:00:00 1970 +0000
423 423 | summary: d
424 424 |
425 425 @ changeset: 1:ef3a871183d7
426 426 | user: test
427 427 | date: Thu Jan 01 00:00:00 1970 +0000
428 428 | summary: b
429 429 |
430 430 o changeset: 0:9ab35a2d17cb
431 431 user: test
432 432 date: Thu Jan 01 00:00:00 1970 +0000
433 433 summary: a
434 434
435 435 $ restore
436 436
437 437 2 different branches and a common ancestor: 1 strip
438 438
439 439 $ hg strip 1 "2|4"
440 440 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
441 441 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
442 442 $ restore
443 443
444 444 verify fncache is kept up-to-date
445 445
446 446 $ touch a
447 447 $ hg ci -qAm a
448 448 #if repofncache
449 449 $ cat .hg/store/fncache | sort
450 450 data/a.i
451 451 data/bar.i
452 452 #endif
453 453
454 454 $ hg strip tip
455 455 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
456 456 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
457 457 #if repofncache
458 458 $ cat .hg/store/fncache
459 459 data/bar.i
460 460 #endif
461 461
462 462 stripping an empty revset
463 463
464 464 $ hg strip "1 and not 1"
465 465 abort: empty revision set
466 466 [255]
467 467
468 468 remove branchy history for qimport tests
469 469
470 470 $ hg strip 3
471 471 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
472 472
473 473
474 474 strip of applied mq should cleanup status file
475 475
476 476 $ echo "mq=" >> $HGRCPATH
477 477 $ hg up -C 3
478 478 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
479 479 $ echo fooagain >> bar
480 480 $ hg ci -mf
481 481 $ hg qimport -r tip:2
482 482
483 483 applied patches before strip
484 484
485 485 $ hg qapplied
486 486 d
487 487 e
488 488 f
489 489
490 490 stripping revision in queue
491 491
492 492 $ hg strip 3
493 493 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
494 494 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
495 495
496 496 applied patches after stripping rev in queue
497 497
498 498 $ hg qapplied
499 499 d
500 500
501 501 stripping ancestor of queue
502 502
503 503 $ hg strip 1
504 504 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
505 505 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
506 506
507 507 applied patches after stripping ancestor of queue
508 508
509 509 $ hg qapplied
510 510
511 511 Verify strip protects against stripping wc parent when there are uncommitted mods
512 512
513 513 $ echo b > b
514 514 $ echo bb > bar
515 515 $ hg add b
516 516 $ hg ci -m 'b'
517 517 $ hg log --graph
518 518 @ changeset: 1:76dcf9fab855
519 519 | tag: tip
520 520 | user: test
521 521 | date: Thu Jan 01 00:00:00 1970 +0000
522 522 | summary: b
523 523 |
524 524 o changeset: 0:9ab35a2d17cb
525 525 user: test
526 526 date: Thu Jan 01 00:00:00 1970 +0000
527 527 summary: a
528 528
529 529 $ hg up 0
530 530 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
531 531 $ echo c > bar
532 532 $ hg up -t false
533 533 merging bar
534 534 merging bar failed!
535 535 1 files updated, 0 files merged, 0 files removed, 1 files unresolved
536 536 use 'hg resolve' to retry unresolved file merges
537 537 [1]
538 538 $ hg sum
539 539 parent: 1:76dcf9fab855 tip
540 540 b
541 541 branch: default
542 542 commit: 1 modified, 1 unknown, 1 unresolved
543 543 update: (current)
544 544 phases: 2 draft
545 545 mq: 3 unapplied
546 546
547 547 $ echo c > b
548 548 $ hg strip tip
549 549 abort: local changes found
550 550 [255]
551 551 $ hg strip tip --keep
552 552 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
553 553 $ hg log --graph
554 554 @ changeset: 0:9ab35a2d17cb
555 555 tag: tip
556 556 user: test
557 557 date: Thu Jan 01 00:00:00 1970 +0000
558 558 summary: a
559 559
560 560 $ hg status
561 561 M bar
562 562 ? b
563 563 ? bar.orig
564 564
565 565 $ rm bar.orig
566 566 $ hg sum
567 567 parent: 0:9ab35a2d17cb tip
568 568 a
569 569 branch: default
570 570 commit: 1 modified, 1 unknown
571 571 update: (current)
572 572 phases: 1 draft
573 573 mq: 3 unapplied
574 574
575 575 Strip adds, removes, modifies with --keep
576 576
577 577 $ touch b
578 578 $ hg add b
579 579 $ hg commit -mb
580 580 $ touch c
581 581
582 582 ... with a clean working dir
583 583
584 584 $ hg add c
585 585 $ hg rm bar
586 586 $ hg commit -mc
587 587 $ hg status
588 588 $ hg strip --keep tip
589 589 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
590 590 $ hg status
591 591 ! bar
592 592 ? c
593 593
594 594 ... with a dirty working dir
595 595
596 596 $ hg add c
597 597 $ hg rm bar
598 598 $ hg commit -mc
599 599 $ hg status
600 600 $ echo b > b
601 601 $ echo d > d
602 602 $ hg strip --keep tip
603 603 saved backup bundle to $TESTTMP/test/.hg/strip-backup/*-backup.hg (glob)
604 604 $ hg status
605 605 M b
606 606 ! bar
607 607 ? c
608 608 ? d
609 609
610 610 ... after updating the dirstate
611 611 $ hg add c
612 612 $ hg commit -mc
613 613 $ hg rm c
614 614 $ hg commit -mc
615 615 $ hg strip --keep '.^' -q
616 616 $ cd ..
617 617
618 618 stripping many nodes on a complex graph (issue3299)
619 619
620 620 $ hg init issue3299
621 621 $ cd issue3299
622 622 $ hg debugbuilddag '@a.:a@b.:b.:x<a@a.:a<b@b.:b<a@a.:a'
623 623 $ hg strip 'not ancestors(x)'
624 624 saved backup bundle to $TESTTMP/issue3299/.hg/strip-backup/*-backup.hg (glob)
625 625
626 626 test hg strip -B bookmark
627 627
628 628 $ cd ..
629 629 $ hg init bookmarks
630 630 $ cd bookmarks
631 631 $ hg debugbuilddag '..<2.*1/2:m<2+3:c<m+3:a<2.:b<m+2:d<2.:e<m+1:f'
632 632 $ hg bookmark -r 'a' 'todelete'
633 633 $ hg bookmark -r 'b' 'B'
634 634 $ hg bookmark -r 'b' 'nostrip'
635 635 $ hg bookmark -r 'c' 'delete'
636 636 $ hg bookmark -r 'd' 'multipledelete1'
637 637 $ hg bookmark -r 'e' 'multipledelete2'
638 638 $ hg bookmark -r 'f' 'singlenode1'
639 639 $ hg bookmark -r 'f' 'singlenode2'
640 640 $ hg up -C todelete
641 641 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
642 642 (activating bookmark todelete)
643 643 $ hg strip -B nostrip
644 644 bookmark 'nostrip' deleted
645 645 abort: empty revision set
646 646 [255]
647 647 $ hg strip -B todelete
648 648 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
649 649 saved backup bundle to $TESTTMP/bookmarks/.hg/strip-backup/*-backup.hg (glob)
650 650 bookmark 'todelete' deleted
651 651 $ hg id -ir dcbb326fdec2
652 652 abort: unknown revision 'dcbb326fdec2'!
653 653 [255]
654 654 $ hg id -ir d62d843c9a01
655 655 d62d843c9a01
656 656 $ hg bookmarks
657 657 B 9:ff43616e5d0f
658 658 delete 6:2702dd0c91e7
659 659 multipledelete1 11:e46a4836065c
660 660 multipledelete2 12:b4594d867745
661 661 singlenode1 13:43227190fef8
662 662 singlenode2 13:43227190fef8
663 663 $ hg strip -B multipledelete1 -B multipledelete2
664 664 saved backup bundle to $TESTTMP/bookmarks/.hg/strip-backup/e46a4836065c-89ec65c2-backup.hg
665 665 bookmark 'multipledelete1' deleted
666 666 bookmark 'multipledelete2' deleted
667 667 $ hg id -ir e46a4836065c
668 668 abort: unknown revision 'e46a4836065c'!
669 669 [255]
670 670 $ hg id -ir b4594d867745
671 671 abort: unknown revision 'b4594d867745'!
672 672 [255]
673 673 $ hg strip -B singlenode1 -B singlenode2
674 674 saved backup bundle to $TESTTMP/bookmarks/.hg/strip-backup/43227190fef8-8da858f2-backup.hg
675 675 bookmark 'singlenode1' deleted
676 676 bookmark 'singlenode2' deleted
677 677 $ hg id -ir 43227190fef8
678 678 abort: unknown revision '43227190fef8'!
679 679 [255]
680 680 $ hg strip -B unknownbookmark
681 681 abort: bookmark 'unknownbookmark' not found
682 682 [255]
683 683 $ hg strip -B unknownbookmark1 -B unknownbookmark2
684 684 abort: bookmark 'unknownbookmark1,unknownbookmark2' not found
685 685 [255]
686 686 $ hg strip -B delete -B unknownbookmark
687 687 abort: bookmark 'unknownbookmark' not found
688 688 [255]
689 689 $ hg strip -B delete
690 690 saved backup bundle to $TESTTMP/bookmarks/.hg/strip-backup/*-backup.hg (glob)
691 691 bookmark 'delete' deleted
692 692 $ hg id -ir 6:2702dd0c91e7
693 693 abort: unknown revision '2702dd0c91e7'!
694 694 [255]
695 695 $ hg update B
696 696 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
697 697 (activating bookmark B)
698 698 $ echo a > a
699 699 $ hg add a
700 700 $ hg strip -B B
701 701 abort: local changes found
702 702 [255]
703 703 $ hg bookmarks
704 704 * B 6:ff43616e5d0f
705 705
706 706 Make sure no one adds back a -b option:
707 707
708 708 $ hg strip -b tip
709 709 hg strip: option -b not recognized
710 710 hg strip [-k] [-f] [-B bookmark] [-r] REV...
711 711
712 712 strip changesets and all their descendants from the repository
713 713
714 714 (use 'hg help -e strip' to show help for the strip extension)
715 715
716 716 options ([+] can be repeated):
717 717
718 718 -r --rev REV [+] strip specified revision (optional, can specify
719 719 revisions without this option)
720 720 -f --force force removal of changesets, discard uncommitted
721 721 changes (no backup)
722 722 --no-backup no backups
723 723 -k --keep do not modify working directory during strip
724 724 -B --bookmark VALUE [+] remove revs only reachable from given bookmark
725 725 --mq operate on patch repository
726 726
727 727 (use 'hg strip -h' to show more help)
728 728 [255]
729 729
730 730 $ cd ..
731 731
732 732 Verify bundles don't get overwritten:
733 733
734 734 $ hg init doublebundle
735 735 $ cd doublebundle
736 736 $ touch a
737 737 $ hg commit -Aqm a
738 738 $ touch b
739 739 $ hg commit -Aqm b
740 740 $ hg strip -r 0
741 741 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
742 742 saved backup bundle to $TESTTMP/doublebundle/.hg/strip-backup/3903775176ed-e68910bd-backup.hg
743 743 $ ls .hg/strip-backup
744 744 3903775176ed-e68910bd-backup.hg
745 745 #if repobundlerepo
746 746 $ hg pull -q -r 3903775176ed .hg/strip-backup/3903775176ed-e68910bd-backup.hg
747 747 $ hg strip -r 0
748 748 saved backup bundle to $TESTTMP/doublebundle/.hg/strip-backup/3903775176ed-54390173-backup.hg
749 749 $ ls .hg/strip-backup
750 750 3903775176ed-54390173-backup.hg
751 751 3903775176ed-e68910bd-backup.hg
752 752 #endif
753 753 $ cd ..
754 754
755 755 Test that we only bundle the stripped changesets (issue4736)
756 756 ------------------------------------------------------------
757 757
758 758 initialization (previous repo is empty anyway)
759 759
760 760 $ hg init issue4736
761 761 $ cd issue4736
762 762 $ echo a > a
763 763 $ hg add a
764 764 $ hg commit -m commitA
765 765 $ echo b > b
766 766 $ hg add b
767 767 $ hg commit -m commitB
768 768 $ echo c > c
769 769 $ hg add c
770 770 $ hg commit -m commitC
771 771 $ hg up 'desc(commitB)'
772 772 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
773 773 $ echo d > d
774 774 $ hg add d
775 775 $ hg commit -m commitD
776 776 created new head
777 777 $ hg up 'desc(commitC)'
778 778 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
779 779 $ hg merge 'desc(commitD)'
780 780 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
781 781 (branch merge, don't forget to commit)
782 782 $ hg ci -m 'mergeCD'
783 783 $ hg log -G
784 784 @ changeset: 4:d8db9d137221
785 785 |\ tag: tip
786 786 | | parent: 2:5c51d8d6557d
787 787 | | parent: 3:6625a5168474
788 788 | | user: test
789 789 | | date: Thu Jan 01 00:00:00 1970 +0000
790 790 | | summary: mergeCD
791 791 | |
792 792 | o changeset: 3:6625a5168474
793 793 | | parent: 1:eca11cf91c71
794 794 | | user: test
795 795 | | date: Thu Jan 01 00:00:00 1970 +0000
796 796 | | summary: commitD
797 797 | |
798 798 o | changeset: 2:5c51d8d6557d
799 799 |/ user: test
800 800 | date: Thu Jan 01 00:00:00 1970 +0000
801 801 | summary: commitC
802 802 |
803 803 o changeset: 1:eca11cf91c71
804 804 | user: test
805 805 | date: Thu Jan 01 00:00:00 1970 +0000
806 806 | summary: commitB
807 807 |
808 808 o changeset: 0:105141ef12d0
809 809 user: test
810 810 date: Thu Jan 01 00:00:00 1970 +0000
811 811 summary: commitA
812 812
813 813
814 814 Check bundle behavior:
815 815
816 816 $ hg bundle -r 'desc(mergeCD)' --base 'desc(commitC)' ../issue4736.hg
817 817 2 changesets found
818 818 #if repobundlerepo
819 819 $ hg log -r 'bundle()' -R ../issue4736.hg
820 820 changeset: 3:6625a5168474
821 821 parent: 1:eca11cf91c71
822 822 user: test
823 823 date: Thu Jan 01 00:00:00 1970 +0000
824 824 summary: commitD
825 825
826 826 changeset: 4:d8db9d137221
827 827 tag: tip
828 828 parent: 2:5c51d8d6557d
829 829 parent: 3:6625a5168474
830 830 user: test
831 831 date: Thu Jan 01 00:00:00 1970 +0000
832 832 summary: mergeCD
833 833
834 834 #endif
835 835
836 836 check strip behavior
837 837
838 838 $ hg --config extensions.strip= strip 'desc(commitD)' --debug
839 839 resolving manifests
840 840 branchmerge: False, force: True, partial: False
841 841 ancestor: d8db9d137221+, local: d8db9d137221+, remote: eca11cf91c71
842 842 c: other deleted -> r
843 843 removing c
844 844 d: other deleted -> r
845 845 removing d
846 846 starting 4 threads for background file closing (?)
847 847 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
848 848 2 changesets found
849 849 list of changesets:
850 850 6625a516847449b6f0fa3737b9ba56e9f0f3032c
851 851 d8db9d1372214336d2b5570f20ee468d2c72fa8b
852 852 bundle2-output-bundle: "HG20", (1 params) 3 parts total
853 853 bundle2-output-part: "changegroup" (params: 1 mandatory 1 advisory) streamed payload
854 854 bundle2-output-part: "cache:rev-branch-cache" streamed payload
855 855 bundle2-output-part: "phase-heads" 24 bytes payload
856 856 saved backup bundle to $TESTTMP/issue4736/.hg/strip-backup/6625a5168474-345bb43d-backup.hg
857 857 updating the branch cache
858 858 invalid branchheads cache (served): tip differs
859 859 $ hg log -G
860 860 o changeset: 2:5c51d8d6557d
861 861 | tag: tip
862 862 | user: test
863 863 | date: Thu Jan 01 00:00:00 1970 +0000
864 864 | summary: commitC
865 865 |
866 866 @ changeset: 1:eca11cf91c71
867 867 | user: test
868 868 | date: Thu Jan 01 00:00:00 1970 +0000
869 869 | summary: commitB
870 870 |
871 871 o changeset: 0:105141ef12d0
872 872 user: test
873 873 date: Thu Jan 01 00:00:00 1970 +0000
874 874 summary: commitA
875 875
876 876
877 877 strip backup content
878 878
879 879 #if repobundlerepo
880 880 $ hg log -r 'bundle()' -R .hg/strip-backup/6625a5168474-*-backup.hg
881 881 changeset: 3:6625a5168474
882 882 parent: 1:eca11cf91c71
883 883 user: test
884 884 date: Thu Jan 01 00:00:00 1970 +0000
885 885 summary: commitD
886 886
887 887 changeset: 4:d8db9d137221
888 888 tag: tip
889 889 parent: 2:5c51d8d6557d
890 890 parent: 3:6625a5168474
891 891 user: test
892 892 date: Thu Jan 01 00:00:00 1970 +0000
893 893 summary: mergeCD
894 894
895 895
896 896 #endif
897 897
898 898 Check that the phase cache is properly invalidated after a strip with bookmark.
899 899
900 900 $ cat > ../stripstalephasecache.py << EOF
901 901 > from mercurial import extensions, localrepo
902 902 > def transactioncallback(orig, repo, desc, *args, **kwargs):
903 903 > def test(transaction):
904 904 > # observe cache inconsistency
905 905 > try:
906 906 > [repo.changelog.node(r) for r in repo.revs(b"not public()")]
907 907 > except IndexError:
908 908 > repo.ui.status(b"Index error!\n")
909 909 > transaction = orig(repo, desc, *args, **kwargs)
910 910 > # warm up the phase cache
911 911 > list(repo.revs(b"not public()"))
912 912 > if desc != b'strip':
913 913 > transaction.addpostclose(b"phase invalidation test", test)
914 914 > return transaction
915 915 > def extsetup(ui):
916 916 > extensions.wrapfunction(localrepo.localrepository, b"transaction",
917 917 > transactioncallback)
918 918 > EOF
919 919 $ hg up -C 2
920 920 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
921 921 $ echo k > k
922 922 $ hg add k
923 923 $ hg commit -m commitK
924 924 $ echo l > l
925 925 $ hg add l
926 926 $ hg commit -m commitL
927 927 $ hg book -r tip blah
928 928 $ hg strip ".^" --config extensions.crash=$TESTTMP/stripstalephasecache.py
929 929 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
930 930 saved backup bundle to $TESTTMP/issue4736/.hg/strip-backup/8f0b4384875c-4fa10deb-backup.hg
931 931 $ hg up -C 1
932 932 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
933 933
934 934 Error during post-close callback of the strip transaction
935 935 (They should be gracefully handled and reported)
936 936
937 937 $ cat > ../crashstrip.py << EOF
938 938 > from mercurial import error
939 939 > def reposetup(ui, repo):
940 940 > class crashstriprepo(repo.__class__):
941 941 > def transaction(self, desc, *args, **kwargs):
942 942 > tr = super(crashstriprepo, self).transaction(desc, *args, **kwargs)
943 943 > if desc == b'strip':
944 944 > def crash(tra): raise error.Abort(b'boom')
945 945 > tr.addpostclose(b'crash', crash)
946 946 > return tr
947 947 > repo.__class__ = crashstriprepo
948 948 > EOF
949 949 $ hg strip tip --config extensions.crash=$TESTTMP/crashstrip.py
950 950 saved backup bundle to $TESTTMP/issue4736/.hg/strip-backup/5c51d8d6557d-70daef06-backup.hg
951 951 strip failed, backup bundle stored in '$TESTTMP/issue4736/.hg/strip-backup/5c51d8d6557d-70daef06-backup.hg'
952 952 abort: boom
953 953 [255]
954 954
955 955 test stripping a working directory parent doesn't switch named branches
956 956
957 957 $ hg log -G
958 958 @ changeset: 1:eca11cf91c71
959 959 | tag: tip
960 960 | user: test
961 961 | date: Thu Jan 01 00:00:00 1970 +0000
962 962 | summary: commitB
963 963 |
964 964 o changeset: 0:105141ef12d0
965 965 user: test
966 966 date: Thu Jan 01 00:00:00 1970 +0000
967 967 summary: commitA
968 968
969 969
970 970 $ hg branch new-branch
971 971 marked working directory as branch new-branch
972 972 (branches are permanent and global, did you want a bookmark?)
973 973 $ hg ci -m "start new branch"
974 974 $ echo 'foo' > foo.txt
975 975 $ hg ci -Aqm foo
976 976 $ hg up default
977 977 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
978 978 $ echo 'bar' > bar.txt
979 979 $ hg ci -Aqm bar
980 980 $ hg up new-branch
981 981 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
982 982 $ hg merge default
983 983 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
984 984 (branch merge, don't forget to commit)
985 985 $ hg log -G
986 986 @ changeset: 4:35358f982181
987 987 | tag: tip
988 988 | parent: 1:eca11cf91c71
989 989 | user: test
990 990 | date: Thu Jan 01 00:00:00 1970 +0000
991 991 | summary: bar
992 992 |
993 993 | @ changeset: 3:f62c6c09b707
994 994 | | branch: new-branch
995 995 | | user: test
996 996 | | date: Thu Jan 01 00:00:00 1970 +0000
997 997 | | summary: foo
998 998 | |
999 999 | o changeset: 2:b1d33a8cadd9
1000 1000 |/ branch: new-branch
1001 1001 | user: test
1002 1002 | date: Thu Jan 01 00:00:00 1970 +0000
1003 1003 | summary: start new branch
1004 1004 |
1005 1005 o changeset: 1:eca11cf91c71
1006 1006 | user: test
1007 1007 | date: Thu Jan 01 00:00:00 1970 +0000
1008 1008 | summary: commitB
1009 1009 |
1010 1010 o changeset: 0:105141ef12d0
1011 1011 user: test
1012 1012 date: Thu Jan 01 00:00:00 1970 +0000
1013 1013 summary: commitA
1014 1014
1015 1015
1016 1016 $ hg strip --force -r 35358f982181
1017 1017 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1018 1018 saved backup bundle to $TESTTMP/issue4736/.hg/strip-backup/35358f982181-50d992d4-backup.hg
1019 1019 $ hg log -G
1020 1020 @ changeset: 3:f62c6c09b707
1021 1021 | branch: new-branch
1022 1022 | tag: tip
1023 1023 | user: test
1024 1024 | date: Thu Jan 01 00:00:00 1970 +0000
1025 1025 | summary: foo
1026 1026 |
1027 1027 o changeset: 2:b1d33a8cadd9
1028 1028 | branch: new-branch
1029 1029 | user: test
1030 1030 | date: Thu Jan 01 00:00:00 1970 +0000
1031 1031 | summary: start new branch
1032 1032 |
1033 1033 o changeset: 1:eca11cf91c71
1034 1034 | user: test
1035 1035 | date: Thu Jan 01 00:00:00 1970 +0000
1036 1036 | summary: commitB
1037 1037 |
1038 1038 o changeset: 0:105141ef12d0
1039 1039 user: test
1040 1040 date: Thu Jan 01 00:00:00 1970 +0000
1041 1041 summary: commitA
1042 1042
1043 1043
1044 1044 $ hg up default
1045 1045 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1046 1046 $ echo 'bar' > bar.txt
1047 1047 $ hg ci -Aqm bar
1048 1048 $ hg up new-branch
1049 1049 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1050 1050 $ hg merge default
1051 1051 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1052 1052 (branch merge, don't forget to commit)
1053 1053 $ hg ci -m merge
1054 1054 $ hg log -G
1055 1055 @ changeset: 5:4cf5e92caec2
1056 1056 |\ branch: new-branch
1057 1057 | | tag: tip
1058 1058 | | parent: 3:f62c6c09b707
1059 1059 | | parent: 4:35358f982181
1060 1060 | | user: test
1061 1061 | | date: Thu Jan 01 00:00:00 1970 +0000
1062 1062 | | summary: merge
1063 1063 | |
1064 1064 | o changeset: 4:35358f982181
1065 1065 | | parent: 1:eca11cf91c71
1066 1066 | | user: test
1067 1067 | | date: Thu Jan 01 00:00:00 1970 +0000
1068 1068 | | summary: bar
1069 1069 | |
1070 1070 o | changeset: 3:f62c6c09b707
1071 1071 | | branch: new-branch
1072 1072 | | user: test
1073 1073 | | date: Thu Jan 01 00:00:00 1970 +0000
1074 1074 | | summary: foo
1075 1075 | |
1076 1076 o | changeset: 2:b1d33a8cadd9
1077 1077 |/ branch: new-branch
1078 1078 | user: test
1079 1079 | date: Thu Jan 01 00:00:00 1970 +0000
1080 1080 | summary: start new branch
1081 1081 |
1082 1082 o changeset: 1:eca11cf91c71
1083 1083 | user: test
1084 1084 | date: Thu Jan 01 00:00:00 1970 +0000
1085 1085 | summary: commitB
1086 1086 |
1087 1087 o changeset: 0:105141ef12d0
1088 1088 user: test
1089 1089 date: Thu Jan 01 00:00:00 1970 +0000
1090 1090 summary: commitA
1091 1091
1092 1092
1093 1093 $ hg strip -r 35358f982181
1094 1094 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1095 1095 saved backup bundle to $TESTTMP/issue4736/.hg/strip-backup/35358f982181-a6f020aa-backup.hg
1096 1096 $ hg log -G
1097 1097 @ changeset: 3:f62c6c09b707
1098 1098 | branch: new-branch
1099 1099 | tag: tip
1100 1100 | user: test
1101 1101 | date: Thu Jan 01 00:00:00 1970 +0000
1102 1102 | summary: foo
1103 1103 |
1104 1104 o changeset: 2:b1d33a8cadd9
1105 1105 | branch: new-branch
1106 1106 | user: test
1107 1107 | date: Thu Jan 01 00:00:00 1970 +0000
1108 1108 | summary: start new branch
1109 1109 |
1110 1110 o changeset: 1:eca11cf91c71
1111 1111 | user: test
1112 1112 | date: Thu Jan 01 00:00:00 1970 +0000
1113 1113 | summary: commitB
1114 1114 |
1115 1115 o changeset: 0:105141ef12d0
1116 1116 user: test
1117 1117 date: Thu Jan 01 00:00:00 1970 +0000
1118 1118 summary: commitA
1119 1119
1120 1120
1121 1121 $ hg unbundle -u $TESTTMP/issue4736/.hg/strip-backup/35358f982181-a6f020aa-backup.hg
1122 1122 adding changesets
1123 1123 adding manifests
1124 1124 adding file changes
1125 1125 added 2 changesets with 1 changes to 1 files
1126 1126 new changesets 35358f982181:4cf5e92caec2
1127 1127 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1128 1128
1129 1129 $ hg strip -k -r 35358f982181
1130 1130 saved backup bundle to $TESTTMP/issue4736/.hg/strip-backup/35358f982181-a6f020aa-backup.hg
1131 1131 $ hg log -G
1132 1132 @ changeset: 3:f62c6c09b707
1133 1133 | branch: new-branch
1134 1134 | tag: tip
1135 1135 | user: test
1136 1136 | date: Thu Jan 01 00:00:00 1970 +0000
1137 1137 | summary: foo
1138 1138 |
1139 1139 o changeset: 2:b1d33a8cadd9
1140 1140 | branch: new-branch
1141 1141 | user: test
1142 1142 | date: Thu Jan 01 00:00:00 1970 +0000
1143 1143 | summary: start new branch
1144 1144 |
1145 1145 o changeset: 1:eca11cf91c71
1146 1146 | user: test
1147 1147 | date: Thu Jan 01 00:00:00 1970 +0000
1148 1148 | summary: commitB
1149 1149 |
1150 1150 o changeset: 0:105141ef12d0
1151 1151 user: test
1152 1152 date: Thu Jan 01 00:00:00 1970 +0000
1153 1153 summary: commitA
1154 1154
1155 1155 $ hg diff
1156 1156 diff -r f62c6c09b707 bar.txt
1157 1157 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1158 1158 +++ b/bar.txt Thu Jan 01 00:00:00 1970 +0000
1159 1159 @@ -0,0 +1,1 @@
1160 1160 +bar
1161 1161
1162 1162 Use delayedstrip to strip inside a transaction
1163 1163
1164 1164 $ cd $TESTTMP
1165 1165 $ hg init delayedstrip
1166 1166 $ cd delayedstrip
1167 1167 $ hg debugdrawdag <<'EOS'
1168 1168 > D
1169 1169 > |
1170 1170 > C F H # Commit on top of "I",
1171 1171 > | |/| # Strip B+D+I+E+G+H+Z
1172 1172 > I B E G
1173 1173 > \|/
1174 1174 > A Z
1175 1175 > EOS
1176 1176 $ cp -R . ../scmutilcleanup
1177 1177
1178 1178 $ hg up -C I
1179 1179 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1180 1180 $ echo 3 >> I
1181 1181 $ cat > $TESTTMP/delayedstrip.py <<EOF
1182 1182 > from __future__ import absolute_import
1183 1183 > from mercurial import commands, registrar, repair
1184 1184 > cmdtable = {}
1185 1185 > command = registrar.command(cmdtable)
1186 1186 > @command(b'testdelayedstrip')
1187 1187 > def testdelayedstrip(ui, repo):
1188 1188 > def getnodes(expr):
1189 1189 > return [repo.changelog.node(r) for r in repo.revs(expr)]
1190 1190 > with repo.wlock():
1191 1191 > with repo.lock():
1192 1192 > with repo.transaction(b'delayedstrip'):
1193 1193 > repair.delayedstrip(ui, repo, getnodes(b'B+I+Z+D+E'), b'J')
1194 1194 > repair.delayedstrip(ui, repo, getnodes(b'G+H+Z'), b'I')
1195 1195 > commands.commit(ui, repo, message=b'J', date=b'0 0')
1196 1196 > EOF
1197 1197 $ hg testdelayedstrip --config extensions.t=$TESTTMP/delayedstrip.py
1198 1198 warning: orphaned descendants detected, not stripping 08ebfeb61bac, 112478962961, 7fb047a69f22
1199 1199 saved backup bundle to $TESTTMP/delayedstrip/.hg/strip-backup/f585351a92f8-17475721-I.hg
1200 1200
1201 1201 $ hg log -G -T '{rev}:{node|short} {desc}' -r 'sort(all(), topo)'
1202 1202 @ 6:2f2d51af6205 J
1203 1203 |
1204 1204 o 3:08ebfeb61bac I
1205 1205 |
1206 1206 | o 5:64a8289d2492 F
1207 1207 | |
1208 1208 | o 2:7fb047a69f22 E
1209 1209 |/
1210 1210 | o 4:26805aba1e60 C
1211 1211 | |
1212 1212 | o 1:112478962961 B
1213 1213 |/
1214 1214 o 0:426bada5c675 A
1215 1215
1216 1216 Test high-level scmutil.cleanupnodes API
1217 1217
1218 1218 $ cd $TESTTMP/scmutilcleanup
1219 1219 $ hg debugdrawdag <<'EOS'
1220 1220 > D2 F2 G2 # D2, F2, G2 are replacements for D, F, G
1221 1221 > | | |
1222 1222 > C H G
1223 1223 > EOS
1224 1224 $ for i in B C D F G I Z; do
1225 1225 > hg bookmark -i -r $i b-$i
1226 1226 > done
1227 1227 $ hg bookmark -i -r E 'b-F@divergent1'
1228 1228 $ hg bookmark -i -r H 'b-F@divergent2'
1229 1229 $ hg bookmark -i -r G 'b-F@divergent3'
1230 1230 $ cp -R . ../scmutilcleanup.obsstore
1231 1231
1232 1232 $ cat > $TESTTMP/scmutilcleanup.py <<EOF
1233 1233 > from mercurial import registrar, scmutil
1234 1234 > cmdtable = {}
1235 1235 > command = registrar.command(cmdtable)
1236 1236 > @command(b'testnodescleanup')
1237 1237 > def testnodescleanup(ui, repo):
1238 1238 > def nodes(expr):
1239 1239 > return [repo.changelog.node(r) for r in repo.revs(expr)]
1240 1240 > def node(expr):
1241 1241 > return nodes(expr)[0]
1242 1242 > with repo.wlock():
1243 1243 > with repo.lock():
1244 1244 > with repo.transaction(b'delayedstrip'):
1245 1245 > mapping = {node(b'F'): [node(b'F2')],
1246 1246 > node(b'D'): [node(b'D2')],
1247 1247 > node(b'G'): [node(b'G2')]}
1248 1248 > scmutil.cleanupnodes(repo, mapping, b'replace')
1249 1249 > scmutil.cleanupnodes(repo, nodes(b'((B::)+I+Z)-D2'),
1250 1250 > b'replace')
1251 1251 > EOF
1252 1252 $ hg testnodescleanup --config extensions.t=$TESTTMP/scmutilcleanup.py
1253 1253 warning: orphaned descendants detected, not stripping 112478962961, 1fc8102cda62, 26805aba1e60
1254 1254 saved backup bundle to $TESTTMP/scmutilcleanup/.hg/strip-backup/f585351a92f8-73fb7c03-replace.hg
1255 1255
1256 1256 $ hg log -G -T '{rev}:{node|short} {desc} {bookmarks}' -r 'sort(all(), topo)'
1257 1257 o 8:1473d4b996d1 G2 b-F@divergent3 b-G
1258 1258 |
1259 1259 | o 7:d11b3456a873 F2 b-F
1260 1260 | |
1261 1261 | o 5:5cb05ba470a7 H
1262 1262 |/|
1263 1263 | o 3:7fb047a69f22 E b-F@divergent1
1264 1264 | |
1265 1265 | | o 6:7c78f703e465 D2 b-D
1266 1266 | | |
1267 1267 | | o 4:26805aba1e60 C
1268 1268 | | |
1269 1269 | | o 2:112478962961 B
1270 1270 | |/
1271 1271 o | 1:1fc8102cda62 G
1272 1272 /
1273 1273 o 0:426bada5c675 A b-B b-C b-I
1274 1274
1275 1275 $ hg bookmark
1276 1276 b-B 0:426bada5c675
1277 1277 b-C 0:426bada5c675
1278 1278 b-D 6:7c78f703e465
1279 1279 b-F 7:d11b3456a873
1280 1280 b-F@divergent1 3:7fb047a69f22
1281 1281 b-F@divergent3 8:1473d4b996d1
1282 1282 b-G 8:1473d4b996d1
1283 1283 b-I 0:426bada5c675
1284 1284 b-Z -1:000000000000
1285 1285
1286 1286 Test the above using obsstore "by the way". Not directly related to strip, but
1287 1287 we have reusable code here
1288 1288
1289 1289 $ cd $TESTTMP/scmutilcleanup.obsstore
1290 1290 $ cat >> .hg/hgrc <<EOF
1291 1291 > [experimental]
1292 1292 > evolution=true
1293 1293 > evolution.track-operation=1
1294 1294 > EOF
1295 1295
1296 1296 $ hg testnodescleanup --config extensions.t=$TESTTMP/scmutilcleanup.py
1297 1297 4 new orphan changesets
1298 1298
1299 1299 $ rm .hg/localtags
1300 1300 $ hg log -G -T '{rev}:{node|short} {desc} {bookmarks}' -r 'sort(all(), topo)'
1301 1301 * 12:1473d4b996d1 G2 b-F@divergent3 b-G
1302 1302 |
1303 1303 | * 11:d11b3456a873 F2 b-F
1304 1304 | |
1305 1305 | * 8:5cb05ba470a7 H
1306 1306 |/|
1307 1307 | o 4:7fb047a69f22 E b-F@divergent1
1308 1308 | |
1309 1309 | | * 10:7c78f703e465 D2 b-D
1310 1310 | | |
1311 1311 | | x 6:26805aba1e60 C
1312 1312 | | |
1313 1313 | | x 3:112478962961 B
1314 1314 | |/
1315 1315 x | 1:1fc8102cda62 G
1316 1316 /
1317 1317 o 0:426bada5c675 A b-B b-C b-I
1318 1318
1319 1319 $ hg debugobsolete
1320 1320 1fc8102cda6204549f031015641606ccf5513ec3 1473d4b996d1d1b121de6b39fab6a04fbf9d873e 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '13', 'operation': 'replace', 'user': 'test'}
1321 1321 64a8289d249234b9886244d379f15e6b650b28e3 d11b3456a873daec7c7bc53e5622e8df6d741bd2 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '13', 'operation': 'replace', 'user': 'test'}
1322 1322 f585351a92f85104bff7c284233c338b10eb1df7 7c78f703e465d73102cc8780667ce269c5208a40 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '9', 'operation': 'replace', 'user': 'test'}
1323 1323 48b9aae0607f43ff110d84e6883c151942add5ab 0 {0000000000000000000000000000000000000000} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'replace', 'user': 'test'}
1324 1324 112478962961147124edd43549aedd1a335e44bf 0 {426bada5c67598ca65036d57d9e4b64b0c1ce7a0} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'replace', 'user': 'test'}
1325 1325 08ebfeb61bac6e3f12079de774d285a0d6689eba 0 {426bada5c67598ca65036d57d9e4b64b0c1ce7a0} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'replace', 'user': 'test'}
1326 1326 26805aba1e600a82e93661149f2313866a221a7b 0 {112478962961147124edd43549aedd1a335e44bf} (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'replace', 'user': 'test'}
1327 1327 $ cd ..
1328 1328
1329 1329 Test that obsmarkers are restored even when not using generaldelta
1330 1330
1331 1331 $ hg --config format.usegeneraldelta=no init issue5678
1332 1332 $ cd issue5678
1333 1333 $ cat >> .hg/hgrc <<EOF
1334 1334 > [experimental]
1335 1335 > evolution=true
1336 1336 > EOF
1337 1337 $ echo a > a
1338 1338 $ hg ci -Aqm a
1339 1339 $ hg ci --amend -m a2
1340 1340 $ hg debugobsolete
1341 1341 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b 489bac576828490c0bb8d45eac9e5e172e4ec0a8 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
1342 1342 $ hg strip .
1343 1343 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1344 1344 saved backup bundle to $TESTTMP/issue5678/.hg/strip-backup/489bac576828-bef27e14-backup.hg
1345 1345 $ hg unbundle -q .hg/strip-backup/*
1346 1346 $ hg debugobsolete
1347 1347 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b 489bac576828490c0bb8d45eac9e5e172e4ec0a8 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
1348 1348 $ cd ..
@@ -1,744 +1,744 b''
1 1 setup
2 2
3 3 $ cat >> $HGRCPATH << EOF
4 4 > [extensions]
5 5 > blackbox=
6 6 > mock=$TESTDIR/mockblackbox.py
7 7 > EOF
8 8
9 9 Helper functions:
10 10
11 11 $ cacheexists() {
12 12 > [ -f .hg/cache/tags2-visible ] && echo "tag cache exists" || echo "no tag cache"
13 13 > }
14 14
15 15 $ fnodescacheexists() {
16 16 > [ -f .hg/cache/hgtagsfnodes1 ] && echo "fnodes cache exists" || echo "no fnodes cache"
17 17 > }
18 18
19 19 $ dumptags() {
20 20 > rev=$1
21 21 > echo "rev $rev: .hgtags:"
22 22 > hg cat -r$rev .hgtags
23 23 > }
24 24
25 25 # XXX need to test that the tag cache works when we strip an old head
26 26 # and add a new one rooted off non-tip: i.e. node and rev of tip are the
27 27 # same, but stuff has changed behind tip.
28 28
29 29 Setup:
30 30
31 31 $ hg init t
32 32 $ cd t
33 33 $ cacheexists
34 34 no tag cache
35 35 $ fnodescacheexists
36 36 no fnodes cache
37 37 $ hg id
38 38 000000000000 tip
39 39 $ cacheexists
40 40 no tag cache
41 41 $ fnodescacheexists
42 42 no fnodes cache
43 43 $ echo a > a
44 44 $ hg add a
45 45 $ hg commit -m "test"
46 46 $ hg co
47 47 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
48 48 $ hg identify
49 49 acb14030fe0a tip
50 50 $ hg identify -r 'wdir()'
51 51 acb14030fe0a tip
52 52 $ cacheexists
53 53 tag cache exists
54 54 No fnodes cache because .hgtags file doesn't exist
55 55 (this is an implementation detail)
56 56 $ fnodescacheexists
57 57 no fnodes cache
58 58
59 59 Try corrupting the cache
60 60
61 61 $ printf 'a b' > .hg/cache/tags2-visible
62 62 $ hg identify
63 63 acb14030fe0a tip
64 64 $ cacheexists
65 65 tag cache exists
66 66 $ fnodescacheexists
67 67 no fnodes cache
68 68 $ hg identify
69 69 acb14030fe0a tip
70 70
71 71 Create local tag with long name:
72 72
73 73 $ T=`hg identify --debug --id`
74 74 $ hg tag -l "This is a local tag with a really long name!"
75 75 $ hg tags
76 76 tip 0:acb14030fe0a
77 77 This is a local tag with a really long name! 0:acb14030fe0a
78 78 $ rm .hg/localtags
79 79
80 80 Create a tag behind hg's back:
81 81
82 82 $ echo "$T first" > .hgtags
83 83 $ cat .hgtags
84 84 acb14030fe0a21b60322c440ad2d20cf7685a376 first
85 85 $ hg add .hgtags
86 86 $ hg commit -m "add tags"
87 87 $ hg tags
88 88 tip 1:b9154636be93
89 89 first 0:acb14030fe0a
90 90 $ hg identify
91 91 b9154636be93 tip
92 92
93 93 We should have a fnodes cache now that we have a real tag
94 94 The cache should have an empty entry for rev 0 and a valid entry for rev 1.
95 95
96 96
97 97 $ fnodescacheexists
98 98 fnodes cache exists
99 99 $ f --size --hexdump .hg/cache/hgtagsfnodes1
100 100 .hg/cache/hgtagsfnodes1: size=48
101 101 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
102 102 0010: ff ff ff ff ff ff ff ff b9 15 46 36 26 b7 b4 a7 |..........F6&...|
103 103 0020: 73 e0 9e e3 c5 2f 51 0e 19 e0 5e 1f f9 66 d8 59 |s..../Q...^..f.Y|
104 104
105 105 Repeat with cold tag cache:
106 106
107 107 $ rm -f .hg/cache/tags2-visible .hg/cache/hgtagsfnodes1
108 108 $ hg identify
109 109 b9154636be93 tip
110 110
111 111 $ fnodescacheexists
112 112 fnodes cache exists
113 113 $ f --size --hexdump .hg/cache/hgtagsfnodes1
114 114 .hg/cache/hgtagsfnodes1: size=48
115 115 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
116 116 0010: ff ff ff ff ff ff ff ff b9 15 46 36 26 b7 b4 a7 |..........F6&...|
117 117 0020: 73 e0 9e e3 c5 2f 51 0e 19 e0 5e 1f f9 66 d8 59 |s..../Q...^..f.Y|
118 118
119 119 And again, but now unable to write tag cache or lock file:
120 120
121 121 #if unix-permissions no-fsmonitor
122 122
123 123 $ rm -f .hg/cache/tags2-visible .hg/cache/hgtagsfnodes1
124 124 $ chmod 555 .hg/cache
125 125 $ hg identify
126 126 b9154636be93 tip
127 127 $ chmod 755 .hg/cache
128 128
129 129 (this block should be protected by no-fsmonitor, because "chmod 555 .hg"
130 130 makes watchman fail at accessing to files under .hg)
131 131
132 132 $ chmod 555 .hg
133 133 $ hg identify
134 134 b9154636be93 tip
135 135 $ chmod 755 .hg
136 136 #endif
137 137
138 138 Tag cache debug info written to blackbox log
139 139
140 140 $ rm -f .hg/cache/tags2-visible .hg/cache/hgtagsfnodes1
141 141 $ hg identify
142 142 b9154636be93 tip
143 143 $ hg blackbox -l 6
144 144 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> identify
145 145 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> writing 48 bytes to cache/hgtagsfnodes1
146 146 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> 0/1 cache hits/lookups in * seconds (glob)
147 147 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> writing .hg/cache/tags2-visible with 1 tags
148 148 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> identify exited 0 after * seconds (glob)
149 149 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> blackbox -l 6
150 150
151 151 Failure to acquire lock results in no write
152 152
153 153 $ rm -f .hg/cache/tags2-visible .hg/cache/hgtagsfnodes1
154 154 $ echo 'foo:1' > .hg/wlock
155 155 $ hg identify
156 156 b9154636be93 tip
157 157 $ hg blackbox -l 6
158 158 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> identify
159 159 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> not writing .hg/cache/hgtagsfnodes1 because lock cannot be acquired
160 160 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> 0/1 cache hits/lookups in * seconds (glob)
161 161 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> writing .hg/cache/tags2-visible with 1 tags
162 162 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> identify exited 0 after * seconds (glob)
163 163 1970/01/01 00:00:00 bob @b9154636be938d3d431e75a7c906504a079bfe07 (5000)> blackbox -l 6
164 164
165 165 $ fnodescacheexists
166 166 no fnodes cache
167 167
168 168 $ rm .hg/wlock
169 169
170 170 $ rm -f .hg/cache/tags2-visible .hg/cache/hgtagsfnodes1
171 171 $ hg identify
172 172 b9154636be93 tip
173 173
174 174 Create a branch:
175 175
176 176 $ echo bb > a
177 177 $ hg status
178 178 M a
179 179 $ hg identify
180 180 b9154636be93+ tip
181 181 $ hg co first
182 182 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
183 183 $ hg id
184 184 acb14030fe0a+ first
185 185 $ hg id -r 'wdir()'
186 186 acb14030fe0a+ first
187 187 $ hg -v id
188 188 acb14030fe0a+ first
189 189 $ hg status
190 190 M a
191 191 $ echo 1 > b
192 192 $ hg add b
193 193 $ hg commit -m "branch"
194 194 created new head
195 195
196 196 Creating a new commit shouldn't append the .hgtags fnodes cache until
197 197 tags info is accessed
198 198
199 199 $ f --size --hexdump .hg/cache/hgtagsfnodes1
200 200 .hg/cache/hgtagsfnodes1: size=48
201 201 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
202 202 0010: ff ff ff ff ff ff ff ff b9 15 46 36 26 b7 b4 a7 |..........F6&...|
203 203 0020: 73 e0 9e e3 c5 2f 51 0e 19 e0 5e 1f f9 66 d8 59 |s..../Q...^..f.Y|
204 204
205 205 $ hg id
206 206 c8edf04160c7 tip
207 207
208 208 First 4 bytes of record 3 are changeset fragment
209 209
210 210 $ f --size --hexdump .hg/cache/hgtagsfnodes1
211 211 .hg/cache/hgtagsfnodes1: size=72
212 212 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
213 213 0010: ff ff ff ff ff ff ff ff b9 15 46 36 26 b7 b4 a7 |..........F6&...|
214 214 0020: 73 e0 9e e3 c5 2f 51 0e 19 e0 5e 1f f9 66 d8 59 |s..../Q...^..f.Y|
215 215 0030: c8 ed f0 41 00 00 00 00 00 00 00 00 00 00 00 00 |...A............|
216 216 0040: 00 00 00 00 00 00 00 00 |........|
217 217
218 218 Merge the two heads:
219 219
220 220 $ hg merge 1
221 221 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
222 222 (branch merge, don't forget to commit)
223 223 $ hg blackbox -l3
224 224 1970/01/01 00:00:00 bob @c8edf04160c7f731e4589d66ab3ab3486a64ac28 (5000)> merge 1
225 225 1970/01/01 00:00:00 bob @c8edf04160c7f731e4589d66ab3ab3486a64ac28+b9154636be938d3d431e75a7c906504a079bfe07 (5000)> merge 1 exited 0 after * seconds (glob)
226 226 1970/01/01 00:00:00 bob @c8edf04160c7f731e4589d66ab3ab3486a64ac28+b9154636be938d3d431e75a7c906504a079bfe07 (5000)> blackbox -l3
227 227 $ hg id
228 228 c8edf04160c7+b9154636be93+ tip
229 229 $ hg status
230 230 M .hgtags
231 231 $ hg commit -m "merge"
232 232
233 233 Create a fake head, make sure tag not visible afterwards:
234 234
235 235 $ cp .hgtags tags
236 236 $ hg tag last
237 237 $ hg rm .hgtags
238 238 $ hg commit -m "remove"
239 239
240 240 $ mv tags .hgtags
241 241 $ hg add .hgtags
242 242 $ hg commit -m "readd"
243 243 $
244 244 $ hg tags
245 245 tip 6:35ff301afafe
246 246 first 0:acb14030fe0a
247 247
248 248 Add invalid tags:
249 249
250 250 $ echo "spam" >> .hgtags
251 251 $ echo >> .hgtags
252 252 $ echo "foo bar" >> .hgtags
253 253 $ echo "a5a5 invalid" >> .hg/localtags
254 254 $ cat .hgtags
255 255 acb14030fe0a21b60322c440ad2d20cf7685a376 first
256 256 spam
257 257
258 258 foo bar
259 259 $ hg commit -m "tags"
260 260
261 261 Report tag parse error on other head:
262 262
263 263 $ hg up 3
264 264 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
265 265 $ echo 'x y' >> .hgtags
266 266 $ hg commit -m "head"
267 267 created new head
268 268
269 269 $ hg tags --debug
270 270 .hgtags@75d9f02dfe28, line 2: cannot parse entry
271 271 .hgtags@75d9f02dfe28, line 4: node 'foo' is not well formed
272 272 .hgtags@c4be69a18c11, line 2: node 'x' is not well formed
273 273 tip 8:c4be69a18c11e8bc3a5fdbb576017c25f7d84663
274 274 first 0:acb14030fe0a21b60322c440ad2d20cf7685a376
275 275 $ hg tip
276 276 changeset: 8:c4be69a18c11
277 277 tag: tip
278 278 parent: 3:ac5e980c4dc0
279 279 user: test
280 280 date: Thu Jan 01 00:00:00 1970 +0000
281 281 summary: head
282 282
283 283
284 284 Test tag precedence rules:
285 285
286 286 $ cd ..
287 287 $ hg init t2
288 288 $ cd t2
289 289 $ echo foo > foo
290 290 $ hg add foo
291 291 $ hg ci -m 'add foo' # rev 0
292 292 $ hg tag bar # rev 1
293 293 $ echo >> foo
294 294 $ hg ci -m 'change foo 1' # rev 2
295 295 $ hg up -C 1
296 296 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
297 297 $ hg tag -r 1 -f bar # rev 3
298 298 $ hg up -C 1
299 299 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
300 300 $ echo >> foo
301 301 $ hg ci -m 'change foo 2' # rev 4
302 302 created new head
303 303 $ hg tags
304 304 tip 4:0c192d7d5e6b
305 305 bar 1:78391a272241
306 306
307 307 Repeat in case of cache effects:
308 308
309 309 $ hg tags
310 310 tip 4:0c192d7d5e6b
311 311 bar 1:78391a272241
312 312
313 313 Detailed dump of tag info:
314 314
315 315 $ hg heads -q # expect 4, 3, 2
316 316 4:0c192d7d5e6b
317 317 3:6fa450212aeb
318 318 2:7a94127795a3
319 319 $ dumptags 2
320 320 rev 2: .hgtags:
321 321 bbd179dfa0a71671c253b3ae0aa1513b60d199fa bar
322 322 $ dumptags 3
323 323 rev 3: .hgtags:
324 324 bbd179dfa0a71671c253b3ae0aa1513b60d199fa bar
325 325 bbd179dfa0a71671c253b3ae0aa1513b60d199fa bar
326 326 78391a272241d70354aa14c874552cad6b51bb42 bar
327 327 $ dumptags 4
328 328 rev 4: .hgtags:
329 329 bbd179dfa0a71671c253b3ae0aa1513b60d199fa bar
330 330
331 331 Dump cache:
332 332
333 333 $ cat .hg/cache/tags2-visible
334 334 4 0c192d7d5e6b78a714de54a2e9627952a877e25a
335 335 bbd179dfa0a71671c253b3ae0aa1513b60d199fa bar
336 336 bbd179dfa0a71671c253b3ae0aa1513b60d199fa bar
337 337 78391a272241d70354aa14c874552cad6b51bb42 bar
338 338
339 339 $ f --size --hexdump .hg/cache/hgtagsfnodes1
340 340 .hg/cache/hgtagsfnodes1: size=120
341 341 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
342 342 0010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
343 343 0020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
344 344 0030: 7a 94 12 77 0c 04 f2 a8 af 31 de 17 fa b7 42 28 |z..w.....1....B(|
345 345 0040: 78 ee 5a 2d ad bc 94 3d 6f a4 50 21 7d 3b 71 8c |x.Z-...=o.P!};q.|
346 346 0050: 96 4e f3 7b 89 e5 50 eb da fd 57 89 e7 6c e1 b0 |.N.{..P...W..l..|
347 347 0060: 0c 19 2d 7d 0c 04 f2 a8 af 31 de 17 fa b7 42 28 |..-}.....1....B(|
348 348 0070: 78 ee 5a 2d ad bc 94 3d |x.Z-...=|
349 349
350 350 Corrupt the .hgtags fnodes cache
351 351 Extra junk data at the end should get overwritten on next cache update
352 352
353 353 $ echo extra >> .hg/cache/hgtagsfnodes1
354 354 $ echo dummy1 > foo
355 355 $ hg commit -m throwaway1
356 356
357 357 $ hg tags
358 358 tip 5:8dbfe60eff30
359 359 bar 1:78391a272241
360 360
361 361 $ hg blackbox -l 6
362 362 1970/01/01 00:00:00 bob @8dbfe60eff306a54259cfe007db9e330e7ecf866 (5000)> tags
363 363 1970/01/01 00:00:00 bob @8dbfe60eff306a54259cfe007db9e330e7ecf866 (5000)> writing 24 bytes to cache/hgtagsfnodes1
364 364 1970/01/01 00:00:00 bob @8dbfe60eff306a54259cfe007db9e330e7ecf866 (5000)> 2/3 cache hits/lookups in * seconds (glob)
365 365 1970/01/01 00:00:00 bob @8dbfe60eff306a54259cfe007db9e330e7ecf866 (5000)> writing .hg/cache/tags2-visible with 1 tags
366 366 1970/01/01 00:00:00 bob @8dbfe60eff306a54259cfe007db9e330e7ecf866 (5000)> tags exited 0 after * seconds (glob)
367 367 1970/01/01 00:00:00 bob @8dbfe60eff306a54259cfe007db9e330e7ecf866 (5000)> blackbox -l 6
368 368
369 369 #if unix-permissions no-root
370 370 Errors writing to .hgtags fnodes cache are silently ignored
371 371
372 372 $ echo dummy2 > foo
373 373 $ hg commit -m throwaway2
374 374
375 375 $ chmod a-w .hg/cache/hgtagsfnodes1
376 376 $ rm -f .hg/cache/tags2-visible
377 377
378 378 $ hg tags
379 379 tip 6:b968051b5cf3
380 380 bar 1:78391a272241
381 381
382 382 $ hg blackbox -l 6
383 383 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> tags
384 384 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> couldn't write cache/hgtagsfnodes1: [Errno *] * (glob)
385 385 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> 2/3 cache hits/lookups in * seconds (glob)
386 386 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> writing .hg/cache/tags2-visible with 1 tags
387 387 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> tags exited 0 after * seconds (glob)
388 388 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> blackbox -l 6
389 389
390 390 $ chmod a+w .hg/cache/hgtagsfnodes1
391 391
392 392 $ rm -f .hg/cache/tags2-visible
393 393 $ hg tags
394 394 tip 6:b968051b5cf3
395 395 bar 1:78391a272241
396 396
397 397 $ hg blackbox -l 6
398 398 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> tags
399 399 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> writing 24 bytes to cache/hgtagsfnodes1
400 400 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> 2/3 cache hits/lookups in * seconds (glob)
401 401 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> writing .hg/cache/tags2-visible with 1 tags
402 402 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> tags exited 0 after * seconds (glob)
403 403 1970/01/01 00:00:00 bob @b968051b5cf3f624b771779c6d5f84f1d4c3fb5d (5000)> blackbox -l 6
404 404
405 405 $ f --size .hg/cache/hgtagsfnodes1
406 406 .hg/cache/hgtagsfnodes1: size=168
407 407
408 408 $ hg -q --config extensions.strip= strip -r 6 --no-backup
409 409 #endif
410 410
411 411 Stripping doesn't truncate the tags cache until new data is available
412 412
413 413 $ rm -f .hg/cache/hgtagsfnodes1 .hg/cache/tags2-visible
414 414 $ hg tags
415 415 tip 5:8dbfe60eff30
416 416 bar 1:78391a272241
417 417
418 418 $ f --size .hg/cache/hgtagsfnodes1
419 419 .hg/cache/hgtagsfnodes1: size=144
420 420
421 421 $ hg -q --config extensions.strip= strip -r 5 --no-backup
422 422 $ hg tags
423 423 tip 4:0c192d7d5e6b
424 424 bar 1:78391a272241
425 425
426 426 $ hg blackbox -l 5
427 427 1970/01/01 00:00:00 bob @0c192d7d5e6b78a714de54a2e9627952a877e25a (5000)> writing 24 bytes to cache/hgtagsfnodes1
428 428 1970/01/01 00:00:00 bob @0c192d7d5e6b78a714de54a2e9627952a877e25a (5000)> 2/3 cache hits/lookups in * seconds (glob)
429 429 1970/01/01 00:00:00 bob @0c192d7d5e6b78a714de54a2e9627952a877e25a (5000)> writing .hg/cache/tags2-visible with 1 tags
430 430 1970/01/01 00:00:00 bob @0c192d7d5e6b78a714de54a2e9627952a877e25a (5000)> tags exited 0 after * seconds (glob)
431 431 1970/01/01 00:00:00 bob @0c192d7d5e6b78a714de54a2e9627952a877e25a (5000)> blackbox -l 5
432 432
433 433 $ f --size .hg/cache/hgtagsfnodes1
434 434 .hg/cache/hgtagsfnodes1: size=120
435 435
436 436 $ echo dummy > foo
437 437 $ hg commit -m throwaway3
438 438
439 439 $ hg tags
440 440 tip 5:035f65efb448
441 441 bar 1:78391a272241
442 442
443 443 $ hg blackbox -l 6
444 444 1970/01/01 00:00:00 bob @035f65efb448350f4772141702a81ab1df48c465 (5000)> tags
445 445 1970/01/01 00:00:00 bob @035f65efb448350f4772141702a81ab1df48c465 (5000)> writing 24 bytes to cache/hgtagsfnodes1
446 446 1970/01/01 00:00:00 bob @035f65efb448350f4772141702a81ab1df48c465 (5000)> 2/3 cache hits/lookups in * seconds (glob)
447 447 1970/01/01 00:00:00 bob @035f65efb448350f4772141702a81ab1df48c465 (5000)> writing .hg/cache/tags2-visible with 1 tags
448 448 1970/01/01 00:00:00 bob @035f65efb448350f4772141702a81ab1df48c465 (5000)> tags exited 0 after * seconds (glob)
449 449 1970/01/01 00:00:00 bob @035f65efb448350f4772141702a81ab1df48c465 (5000)> blackbox -l 6
450 450 $ f --size .hg/cache/hgtagsfnodes1
451 451 .hg/cache/hgtagsfnodes1: size=144
452 452
453 453 $ hg -q --config extensions.strip= strip -r 5 --no-backup
454 454
455 455 Test tag removal:
456 456
457 457 $ hg tag --remove bar # rev 5
458 458 $ hg tip -vp
459 459 changeset: 5:5f6e8655b1c7
460 460 tag: tip
461 461 user: test
462 462 date: Thu Jan 01 00:00:00 1970 +0000
463 463 files: .hgtags
464 464 description:
465 465 Removed tag bar
466 466
467 467
468 468 diff -r 0c192d7d5e6b -r 5f6e8655b1c7 .hgtags
469 469 --- a/.hgtags Thu Jan 01 00:00:00 1970 +0000
470 470 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
471 471 @@ -1,1 +1,3 @@
472 472 bbd179dfa0a71671c253b3ae0aa1513b60d199fa bar
473 473 +78391a272241d70354aa14c874552cad6b51bb42 bar
474 474 +0000000000000000000000000000000000000000 bar
475 475
476 476 $ hg tags
477 477 tip 5:5f6e8655b1c7
478 478 $ hg tags # again, try to expose cache bugs
479 479 tip 5:5f6e8655b1c7
480 480
481 481 Remove nonexistent tag:
482 482
483 483 $ hg tag --remove foobar
484 484 abort: tag 'foobar' does not exist
485 485 [255]
486 486 $ hg tip
487 487 changeset: 5:5f6e8655b1c7
488 488 tag: tip
489 489 user: test
490 490 date: Thu Jan 01 00:00:00 1970 +0000
491 491 summary: Removed tag bar
492 492
493 493
494 494 Undo a tag with rollback:
495 495
496 496 $ hg rollback # destroy rev 5 (restore bar)
497 497 repository tip rolled back to revision 4 (undo commit)
498 498 working directory now based on revision 4
499 499 $ hg tags
500 500 tip 4:0c192d7d5e6b
501 501 bar 1:78391a272241
502 502 $ hg tags
503 503 tip 4:0c192d7d5e6b
504 504 bar 1:78391a272241
505 505
506 506 Test tag rank:
507 507
508 508 $ cd ..
509 509 $ hg init t3
510 510 $ cd t3
511 511 $ echo foo > foo
512 512 $ hg add foo
513 513 $ hg ci -m 'add foo' # rev 0
514 514 $ hg tag -f bar # rev 1 bar -> 0
515 515 $ hg tag -f bar # rev 2 bar -> 1
516 516 $ hg tag -fr 0 bar # rev 3 bar -> 0
517 517 $ hg tag -fr 1 bar # rev 4 bar -> 1
518 518 $ hg tag -fr 0 bar # rev 5 bar -> 0
519 519 $ hg tags
520 520 tip 5:85f05169d91d
521 521 bar 0:bbd179dfa0a7
522 522 $ hg co 3
523 523 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
524 524 $ echo barbar > foo
525 525 $ hg ci -m 'change foo' # rev 6
526 526 created new head
527 527 $ hg tags
528 528 tip 6:735c3ca72986
529 529 bar 0:bbd179dfa0a7
530 530
531 531 Don't allow moving tag without -f:
532 532
533 533 $ hg tag -r 3 bar
534 534 abort: tag 'bar' already exists (use -f to force)
535 535 [255]
536 536 $ hg tags
537 537 tip 6:735c3ca72986
538 538 bar 0:bbd179dfa0a7
539 539
540 540 Strip 1: expose an old head:
541 541
542 542 $ hg --config extensions.mq= strip 5
543 543 saved backup bundle to $TESTTMP/t3/.hg/strip-backup/*-backup.hg (glob)
544 544 $ hg tags # partly stale cache
545 545 tip 5:735c3ca72986
546 546 bar 1:78391a272241
547 547 $ hg tags # up-to-date cache
548 548 tip 5:735c3ca72986
549 549 bar 1:78391a272241
550 550
551 551 Strip 2: destroy whole branch, no old head exposed
552 552
553 553 $ hg --config extensions.mq= strip 4
554 554 saved backup bundle to $TESTTMP/t3/.hg/strip-backup/*-backup.hg (glob)
555 555 $ hg tags # partly stale
556 556 tip 4:735c3ca72986
557 557 bar 0:bbd179dfa0a7
558 558 $ rm -f .hg/cache/tags2-visible
559 559 $ hg tags # cold cache
560 560 tip 4:735c3ca72986
561 561 bar 0:bbd179dfa0a7
562 562
563 563 Test tag rank with 3 heads:
564 564
565 565 $ cd ..
566 566 $ hg init t4
567 567 $ cd t4
568 568 $ echo foo > foo
569 569 $ hg add
570 570 adding foo
571 571 $ hg ci -m 'add foo' # rev 0
572 572 $ hg tag bar # rev 1 bar -> 0
573 573 $ hg tag -f bar # rev 2 bar -> 1
574 574 $ hg up -qC 0
575 575 $ hg tag -fr 2 bar # rev 3 bar -> 2
576 576 $ hg tags
577 577 tip 3:197c21bbbf2c
578 578 bar 2:6fa450212aeb
579 579 $ hg up -qC 0
580 580 $ hg tag -m 'retag rev 0' -fr 0 bar # rev 4 bar -> 0, but bar stays at 2
581 581
582 582 Bar should still point to rev 2:
583 583
584 584 $ hg tags
585 585 tip 4:3b4b14ed0202
586 586 bar 2:6fa450212aeb
587 587
588 588 Test that removing global/local tags does not get confused when trying
589 589 to remove a tag of type X which actually only exists as a type Y:
590 590
591 591 $ cd ..
592 592 $ hg init t5
593 593 $ cd t5
594 594 $ echo foo > foo
595 595 $ hg add
596 596 adding foo
597 597 $ hg ci -m 'add foo' # rev 0
598 598
599 599 $ hg tag -r 0 -l localtag
600 600 $ hg tag --remove localtag
601 601 abort: tag 'localtag' is not a global tag
602 602 [255]
603 603 $
604 604 $ hg tag -r 0 globaltag
605 605 $ hg tag --remove -l globaltag
606 606 abort: tag 'globaltag' is not a local tag
607 607 [255]
608 608 $ hg tags -v
609 609 tip 1:a0b6fe111088
610 610 localtag 0:bbd179dfa0a7 local
611 611 globaltag 0:bbd179dfa0a7
612 612
613 613 Test for issue3911
614 614
615 615 $ hg tag -r 0 -l localtag2
616 616 $ hg tag -l --remove localtag2
617 617 $ hg tags -v
618 618 tip 1:a0b6fe111088
619 619 localtag 0:bbd179dfa0a7 local
620 620 globaltag 0:bbd179dfa0a7
621 621
622 622 $ hg tag -r 1 -f localtag
623 623 $ hg tags -v
624 624 tip 2:5c70a037bb37
625 625 localtag 1:a0b6fe111088
626 626 globaltag 0:bbd179dfa0a7
627 627
628 628 $ hg tags -v
629 629 tip 2:5c70a037bb37
630 630 localtag 1:a0b6fe111088
631 631 globaltag 0:bbd179dfa0a7
632 632
633 633 $ hg tag -r 1 localtag2
634 634 $ hg tags -v
635 635 tip 3:bbfb8cd42be2
636 636 localtag2 1:a0b6fe111088
637 637 localtag 1:a0b6fe111088
638 638 globaltag 0:bbd179dfa0a7
639 639
640 640 $ hg tags -v
641 641 tip 3:bbfb8cd42be2
642 642 localtag2 1:a0b6fe111088
643 643 localtag 1:a0b6fe111088
644 644 globaltag 0:bbd179dfa0a7
645 645
646 646 $ cd ..
647 647
648 648 Create a repository with tags data to test .hgtags fnodes transfer
649 649
650 650 $ hg init tagsserver
651 651 $ cd tagsserver
652 652 $ touch foo
653 653 $ hg -q commit -A -m initial
654 654 $ hg tag -m 'tag 0.1' 0.1
655 655 $ echo second > foo
656 656 $ hg commit -m second
657 657 $ hg tag -m 'tag 0.2' 0.2
658 658 $ hg tags
659 659 tip 3:40f0358cb314
660 660 0.2 2:f63cc8fe54e4
661 661 0.1 0:96ee1d7354c4
662 662 $ cd ..
663 663
664 664 Cloning should pull down hgtags fnodes mappings and write the cache file
665 665
666 666 $ hg clone --pull tagsserver tagsclient
667 667 requesting all changes
668 668 adding changesets
669 669 adding manifests
670 670 adding file changes
671 671 added 4 changesets with 4 changes to 2 files
672 672 new changesets 96ee1d7354c4:40f0358cb314
673 673 updating to branch default
674 674 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
675 675
676 676 Missing tags2* files means the cache wasn't written through the normal mechanism.
677 677
678 678 $ ls tagsclient/.hg/cache
679 679 branch2-base
680 680 checkisexec (execbit !)
681 681 checklink (symlink !)
682 682 checklink-target (symlink !)
683 683 hgtagsfnodes1
684 684 rbc-names-v1
685 685 rbc-revs-v1
686 686
687 687 Cache should contain the head only, even though other nodes have tags data
688 688
689 689 $ f --size --hexdump tagsclient/.hg/cache/hgtagsfnodes1
690 690 tagsclient/.hg/cache/hgtagsfnodes1: size=96
691 691 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
692 692 0010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
693 693 0020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
694 694 0030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
695 695 0040: ff ff ff ff ff ff ff ff 40 f0 35 8c 19 e0 a7 d3 |........@.5.....|
696 696 0050: 8a 5c 6a 82 4d cf fb a5 87 d0 2f a3 1e 4f 2f 8a |.\j.M...../..O/.|
697 697
698 698 Running hg tags should produce tags2* file and not change cache
699 699
700 700 $ hg -R tagsclient tags
701 701 tip 3:40f0358cb314
702 702 0.2 2:f63cc8fe54e4
703 703 0.1 0:96ee1d7354c4
704 704
705 705 $ ls tagsclient/.hg/cache
706 706 branch2-base
707 707 checkisexec (execbit !)
708 708 checklink (symlink !)
709 709 checklink-target (symlink !)
710 710 hgtagsfnodes1
711 711 rbc-names-v1
712 712 rbc-revs-v1
713 713 tags2-visible
714 714
715 715 $ f --size --hexdump tagsclient/.hg/cache/hgtagsfnodes1
716 716 tagsclient/.hg/cache/hgtagsfnodes1: size=96
717 717 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
718 718 0010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
719 719 0020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
720 720 0030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
721 721 0040: ff ff ff ff ff ff ff ff 40 f0 35 8c 19 e0 a7 d3 |........@.5.....|
722 722 0050: 8a 5c 6a 82 4d cf fb a5 87 d0 2f a3 1e 4f 2f 8a |.\j.M...../..O/.|
723 723
724 724 Check that the bundle includes cache data
725 725
726 726 $ hg -R tagsclient bundle --all ./test-cache-in-bundle-all-rev.hg
727 727 4 changesets found
728 728 $ hg debugbundle ./test-cache-in-bundle-all-rev.hg
729 729 Stream params: {Compression: BZ}
730 changegroup -- {nbchanges: 4, version: 02}
730 changegroup -- {nbchanges: 4, version: 02} (mandatory: True)
731 731 96ee1d7354c4ad7372047672c36a1f561e3a6a4c
732 732 c4dab0c2fd337eb9191f80c3024830a4889a8f34
733 733 f63cc8fe54e4d326f8d692805d70e092f851ddb1
734 734 40f0358cb314c824a5929ee527308d90e023bc10
735 hgtagsfnodes -- {}
736 cache:rev-branch-cache -- {}
735 hgtagsfnodes -- {} (mandatory: True)
736 cache:rev-branch-cache -- {} (mandatory: True)
737 737
738 738 Check that local clone includes cache data
739 739
740 740 $ hg clone tagsclient tags-local-clone
741 741 updating to branch default
742 742 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
743 743 $ (cd tags-local-clone/.hg/cache/; ls -1 tag*)
744 744 tags2-visible
General Comments 0
You need to be logged in to leave comments. Login now