86 dateutil, |
86 dateutil, |
87 procutil, |
87 procutil, |
88 stringutil, |
88 stringutil, |
89 ) |
89 ) |
90 |
90 |
91 from .revlogutils import ( |
91 from .revlogutils import deltas as deltautil |
92 deltas as deltautil |
|
93 ) |
|
94 |
92 |
95 release = lockmod.release |
93 release = lockmod.release |
96 |
94 |
97 command = registrar.command() |
95 command = registrar.command() |
|
96 |
98 |
97 |
99 @command('debugancestor', [], _('[INDEX] REV1 REV2'), optionalrepo=True) |
98 @command('debugancestor', [], _('[INDEX] REV1 REV2'), optionalrepo=True) |
100 def debugancestor(ui, repo, *args): |
99 def debugancestor(ui, repo, *args): |
101 """find the ancestor revision of two revisions in a given index""" |
100 """find the ancestor revision of two revisions in a given index""" |
102 if len(args) == 3: |
101 if len(args) == 3: |
103 index, rev1, rev2 = args |
102 index, rev1, rev2 = args |
104 r = revlog.revlog(vfsmod.vfs(encoding.getcwd(), audit=False), index) |
103 r = revlog.revlog(vfsmod.vfs(encoding.getcwd(), audit=False), index) |
105 lookup = r.lookup |
104 lookup = r.lookup |
106 elif len(args) == 2: |
105 elif len(args) == 2: |
107 if not repo: |
106 if not repo: |
108 raise error.Abort(_('there is no Mercurial repository here ' |
107 raise error.Abort( |
109 '(.hg not found)')) |
108 _('there is no Mercurial repository here ' '(.hg not found)') |
|
109 ) |
110 rev1, rev2 = args |
110 rev1, rev2 = args |
111 r = repo.changelog |
111 r = repo.changelog |
112 lookup = repo.lookup |
112 lookup = repo.lookup |
113 else: |
113 else: |
114 raise error.Abort(_('either two or three arguments required')) |
114 raise error.Abort(_('either two or three arguments required')) |
115 a = r.ancestor(lookup(rev1), lookup(rev2)) |
115 a = r.ancestor(lookup(rev1), lookup(rev2)) |
116 ui.write('%d:%s\n' % (r.rev(a), hex(a))) |
116 ui.write('%d:%s\n' % (r.rev(a), hex(a))) |
117 |
117 |
|
118 |
118 @command('debugapplystreamclonebundle', [], 'FILE') |
119 @command('debugapplystreamclonebundle', [], 'FILE') |
119 def debugapplystreamclonebundle(ui, repo, fname): |
120 def debugapplystreamclonebundle(ui, repo, fname): |
120 """apply a stream clone bundle file""" |
121 """apply a stream clone bundle file""" |
121 f = hg.openpath(ui, fname) |
122 f = hg.openpath(ui, fname) |
122 gen = exchange.readbundle(ui, f, fname) |
123 gen = exchange.readbundle(ui, f, fname) |
123 gen.apply(repo) |
124 gen.apply(repo) |
124 |
125 |
125 @command('debugbuilddag', |
126 |
126 [('m', 'mergeable-file', None, _('add single file mergeable changes')), |
127 @command( |
127 ('o', 'overwritten-file', None, _('add single file all revs overwrite')), |
128 'debugbuilddag', |
128 ('n', 'new-file', None, _('add new file at each rev'))], |
129 [ |
129 _('[OPTION]... [TEXT]')) |
130 ('m', 'mergeable-file', None, _('add single file mergeable changes')), |
130 def debugbuilddag(ui, repo, text=None, |
131 ( |
131 mergeable_file=False, |
132 'o', |
132 overwritten_file=False, |
133 'overwritten-file', |
133 new_file=False): |
134 None, |
|
135 _('add single file all revs overwrite'), |
|
136 ), |
|
137 ('n', 'new-file', None, _('add new file at each rev')), |
|
138 ], |
|
139 _('[OPTION]... [TEXT]'), |
|
140 ) |
|
141 def debugbuilddag( |
|
142 ui, |
|
143 repo, |
|
144 text=None, |
|
145 mergeable_file=False, |
|
146 overwritten_file=False, |
|
147 new_file=False, |
|
148 ): |
134 """builds a repo with a given DAG from scratch in the current empty repo |
149 """builds a repo with a given DAG from scratch in the current empty repo |
135 |
150 |
136 The description of the DAG is read from stdin if not given on the |
151 The description of the DAG is read from stdin if not given on the |
137 command line. |
152 command line. |
138 |
153 |
268 progress.update(id) |
291 progress.update(id) |
269 |
292 |
270 if tags: |
293 if tags: |
271 repo.vfs.write("localtags", "".join(tags)) |
294 repo.vfs.write("localtags", "".join(tags)) |
272 |
295 |
|
296 |
273 def _debugchangegroup(ui, gen, all=None, indent=0, **opts): |
297 def _debugchangegroup(ui, gen, all=None, indent=0, **opts): |
274 indent_string = ' ' * indent |
298 indent_string = ' ' * indent |
275 if all: |
299 if all: |
276 ui.write(("%sformat: id, p1, p2, cset, delta base, len(delta)\n") |
300 ui.write( |
277 % indent_string) |
301 "%sformat: id, p1, p2, cset, delta base, len(delta)\n" |
|
302 % indent_string |
|
303 ) |
278 |
304 |
279 def showchunks(named): |
305 def showchunks(named): |
280 ui.write("\n%s%s\n" % (indent_string, named)) |
306 ui.write("\n%s%s\n" % (indent_string, named)) |
281 for deltadata in gen.deltaiter(): |
307 for deltadata in gen.deltaiter(): |
282 node, p1, p2, cs, deltabase, delta, flags = deltadata |
308 node, p1, p2, cs, deltabase, delta, flags = deltadata |
283 ui.write("%s%s %s %s %s %s %d\n" % |
309 ui.write( |
284 (indent_string, hex(node), hex(p1), hex(p2), |
310 "%s%s %s %s %s %s %d\n" |
285 hex(cs), hex(deltabase), len(delta))) |
311 % ( |
|
312 indent_string, |
|
313 hex(node), |
|
314 hex(p1), |
|
315 hex(p2), |
|
316 hex(cs), |
|
317 hex(deltabase), |
|
318 len(delta), |
|
319 ) |
|
320 ) |
286 |
321 |
287 chunkdata = gen.changelogheader() |
322 chunkdata = gen.changelogheader() |
288 showchunks("changelog") |
323 showchunks("changelog") |
289 chunkdata = gen.manifestheader() |
324 chunkdata = gen.manifestheader() |
290 showchunks("manifest") |
325 showchunks("manifest") |
320 fm.startitem() |
356 fm.startitem() |
321 fm.plain(indent_string) |
357 fm.plain(indent_string) |
322 cmdutil.showmarker(fm, m) |
358 cmdutil.showmarker(fm, m) |
323 fm.end() |
359 fm.end() |
324 |
360 |
|
361 |
325 def _debugphaseheads(ui, data, indent=0): |
362 def _debugphaseheads(ui, data, indent=0): |
326 """display version and markers contained in 'data'""" |
363 """display version and markers contained in 'data'""" |
327 indent_string = ' ' * indent |
364 indent_string = ' ' * indent |
328 headsbyphase = phases.binarydecode(data) |
365 headsbyphase = phases.binarydecode(data) |
329 for phase in phases.allphases: |
366 for phase in phases.allphases: |
330 for head in headsbyphase[phase]: |
367 for head in headsbyphase[phase]: |
331 ui.write(indent_string) |
368 ui.write(indent_string) |
332 ui.write('%s %s\n' % (hex(head), phases.phasenames[phase])) |
369 ui.write('%s %s\n' % (hex(head), phases.phasenames[phase])) |
333 |
370 |
|
371 |
334 def _quasirepr(thing): |
372 def _quasirepr(thing): |
335 if isinstance(thing, (dict, util.sortdict, collections.OrderedDict)): |
373 if isinstance(thing, (dict, util.sortdict, collections.OrderedDict)): |
336 return '{%s}' % ( |
374 return '{%s}' % ( |
337 b', '.join(b'%s: %s' % (k, thing[k]) for k in sorted(thing))) |
375 b', '.join(b'%s: %s' % (k, thing[k]) for k in sorted(thing)) |
|
376 ) |
338 return pycompat.bytestr(repr(thing)) |
377 return pycompat.bytestr(repr(thing)) |
|
378 |
339 |
379 |
340 def _debugbundle2(ui, gen, all=None, **opts): |
380 def _debugbundle2(ui, gen, all=None, **opts): |
341 """lists the contents of a bundle2""" |
381 """lists the contents of a bundle2""" |
342 if not isinstance(gen, bundle2.unbundle20): |
382 if not isinstance(gen, bundle2.unbundle20): |
343 raise error.Abort(_('not a bundle2 file')) |
383 raise error.Abort(_('not a bundle2 file')) |
358 _debugobsmarkers(ui, part, indent=4, **opts) |
398 _debugobsmarkers(ui, part, indent=4, **opts) |
359 if part.type == 'phase-heads': |
399 if part.type == 'phase-heads': |
360 if not ui.quiet: |
400 if not ui.quiet: |
361 _debugphaseheads(ui, part, indent=4) |
401 _debugphaseheads(ui, part, indent=4) |
362 |
402 |
363 @command('debugbundle', |
403 |
364 [('a', 'all', None, _('show all details')), |
404 @command( |
365 ('', 'part-type', [], _('show only the named part type')), |
405 'debugbundle', |
366 ('', 'spec', None, _('print the bundlespec of the bundle'))], |
406 [ |
367 _('FILE'), |
407 ('a', 'all', None, _('show all details')), |
368 norepo=True) |
408 ('', 'part-type', [], _('show only the named part type')), |
|
409 ('', 'spec', None, _('print the bundlespec of the bundle')), |
|
410 ], |
|
411 _('FILE'), |
|
412 norepo=True, |
|
413 ) |
369 def debugbundle(ui, bundlepath, all=None, spec=None, **opts): |
414 def debugbundle(ui, bundlepath, all=None, spec=None, **opts): |
370 """lists the contents of a bundle""" |
415 """lists the contents of a bundle""" |
371 with hg.openpath(ui, bundlepath) as f: |
416 with hg.openpath(ui, bundlepath) as f: |
372 if spec: |
417 if spec: |
373 spec = exchange.getbundlespec(ui, f) |
418 spec = exchange.getbundlespec(ui, f) |
377 gen = exchange.readbundle(ui, f, bundlepath) |
422 gen = exchange.readbundle(ui, f, bundlepath) |
378 if isinstance(gen, bundle2.unbundle20): |
423 if isinstance(gen, bundle2.unbundle20): |
379 return _debugbundle2(ui, gen, all=all, **opts) |
424 return _debugbundle2(ui, gen, all=all, **opts) |
380 _debugchangegroup(ui, gen, all=all, **opts) |
425 _debugchangegroup(ui, gen, all=all, **opts) |
381 |
426 |
382 @command('debugcapabilities', |
427 |
383 [], _('PATH'), |
428 @command('debugcapabilities', [], _('PATH'), norepo=True) |
384 norepo=True) |
|
385 def debugcapabilities(ui, path, **opts): |
429 def debugcapabilities(ui, path, **opts): |
386 """lists the capabilities of a remote peer""" |
430 """lists the capabilities of a remote peer""" |
387 opts = pycompat.byteskwargs(opts) |
431 opts = pycompat.byteskwargs(opts) |
388 peer = hg.peer(ui, opts, path) |
432 peer = hg.peer(ui, opts, path) |
389 caps = peer.capabilities() |
433 caps = peer.capabilities() |
390 ui.write(('Main capabilities:\n')) |
434 ui.write('Main capabilities:\n') |
391 for c in sorted(caps): |
435 for c in sorted(caps): |
392 ui.write((' %s\n') % c) |
436 ui.write(' %s\n' % c) |
393 b2caps = bundle2.bundle2caps(peer) |
437 b2caps = bundle2.bundle2caps(peer) |
394 if b2caps: |
438 if b2caps: |
395 ui.write(('Bundle2 capabilities:\n')) |
439 ui.write('Bundle2 capabilities:\n') |
396 for key, values in sorted(b2caps.iteritems()): |
440 for key, values in sorted(b2caps.iteritems()): |
397 ui.write((' %s\n') % key) |
441 ui.write(' %s\n' % key) |
398 for v in values: |
442 for v in values: |
399 ui.write((' %s\n') % v) |
443 ui.write(' %s\n' % v) |
|
444 |
400 |
445 |
401 @command('debugcheckstate', [], '') |
446 @command('debugcheckstate', [], '') |
402 def debugcheckstate(ui, repo): |
447 def debugcheckstate(ui, repo): |
403 """validate the correctness of the current dirstate""" |
448 """validate the correctness of the current dirstate""" |
404 parent1, parent2 = repo.dirstate.parents() |
449 parent1, parent2 = repo.dirstate.parents() |
412 errors += 1 |
457 errors += 1 |
413 if state in "a" and f in m1: |
458 if state in "a" and f in m1: |
414 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state)) |
459 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state)) |
415 errors += 1 |
460 errors += 1 |
416 if state in "m" and f not in m1 and f not in m2: |
461 if state in "m" and f not in m1 and f not in m2: |
417 ui.warn(_("%s in state %s, but not in either manifest\n") % |
462 ui.warn( |
418 (f, state)) |
463 _("%s in state %s, but not in either manifest\n") % (f, state) |
|
464 ) |
419 errors += 1 |
465 errors += 1 |
420 for f in m1: |
466 for f in m1: |
421 state = repo.dirstate[f] |
467 state = repo.dirstate[f] |
422 if state not in "nrm": |
468 if state not in "nrm": |
423 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state)) |
469 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state)) |
424 errors += 1 |
470 errors += 1 |
425 if errors: |
471 if errors: |
426 error = _(".hg/dirstate inconsistent with current parent's manifest") |
472 error = _(".hg/dirstate inconsistent with current parent's manifest") |
427 raise error.Abort(error) |
473 raise error.Abort(error) |
428 |
474 |
429 @command('debugcolor', |
475 |
430 [('', 'style', None, _('show all configured styles'))], |
476 @command( |
431 'hg debugcolor') |
477 'debugcolor', |
|
478 [('', 'style', None, _('show all configured styles'))], |
|
479 'hg debugcolor', |
|
480 ) |
432 def debugcolor(ui, repo, **opts): |
481 def debugcolor(ui, repo, **opts): |
433 """show available color, effects or style""" |
482 """show available color, effects or style""" |
434 ui.write(('color mode: %s\n') % stringutil.pprint(ui._colormode)) |
483 ui.write('color mode: %s\n' % stringutil.pprint(ui._colormode)) |
435 if opts.get(r'style'): |
484 if opts.get(r'style'): |
436 return _debugdisplaystyle(ui) |
485 return _debugdisplaystyle(ui) |
437 else: |
486 else: |
438 return _debugdisplaycolor(ui) |
487 return _debugdisplaycolor(ui) |
|
488 |
439 |
489 |
440 def _debugdisplaycolor(ui): |
490 def _debugdisplaycolor(ui): |
441 ui = ui.copy() |
491 ui = ui.copy() |
442 ui._styles.clear() |
492 ui._styles.clear() |
443 for effect in color._activeeffects(ui).keys(): |
493 for effect in color._activeeffects(ui).keys(): |
467 ui.write(': ') |
517 ui.write(': ') |
468 ui.write(' ' * (max(0, width - len(label)))) |
518 ui.write(' ' * (max(0, width - len(label)))) |
469 ui.write(', '.join(ui.label(e, e) for e in effects.split())) |
519 ui.write(', '.join(ui.label(e, e) for e in effects.split())) |
470 ui.write('\n') |
520 ui.write('\n') |
471 |
521 |
|
522 |
472 @command('debugcreatestreamclonebundle', [], 'FILE') |
523 @command('debugcreatestreamclonebundle', [], 'FILE') |
473 def debugcreatestreamclonebundle(ui, repo, fname): |
524 def debugcreatestreamclonebundle(ui, repo, fname): |
474 """create a stream clone bundle file |
525 """create a stream clone bundle file |
475 |
526 |
476 Stream bundles are special bundles that are essentially archives of |
527 Stream bundles are special bundles that are essentially archives of |
477 revlog files. They are commonly used for cloning very quickly. |
528 revlog files. They are commonly used for cloning very quickly. |
478 """ |
529 """ |
479 # TODO we may want to turn this into an abort when this functionality |
530 # TODO we may want to turn this into an abort when this functionality |
480 # is moved into `hg bundle`. |
531 # is moved into `hg bundle`. |
481 if phases.hassecret(repo): |
532 if phases.hassecret(repo): |
482 ui.warn(_('(warning: stream clone bundle will contain secret ' |
533 ui.warn( |
483 'revisions)\n')) |
534 _( |
|
535 '(warning: stream clone bundle will contain secret ' |
|
536 'revisions)\n' |
|
537 ) |
|
538 ) |
484 |
539 |
485 requirements, gen = streamclone.generatebundlev1(repo) |
540 requirements, gen = streamclone.generatebundlev1(repo) |
486 changegroup.writechunks(ui, gen, fname) |
541 changegroup.writechunks(ui, gen, fname) |
487 |
542 |
488 ui.write(_('bundle requirements: %s\n') % ', '.join(sorted(requirements))) |
543 ui.write(_('bundle requirements: %s\n') % ', '.join(sorted(requirements))) |
489 |
544 |
490 @command('debugdag', |
545 |
491 [('t', 'tags', None, _('use tags as labels')), |
546 @command( |
492 ('b', 'branches', None, _('annotate with branch names')), |
547 'debugdag', |
493 ('', 'dots', None, _('use dots for runs')), |
548 [ |
494 ('s', 'spaces', None, _('separate elements by spaces'))], |
549 ('t', 'tags', None, _('use tags as labels')), |
|
550 ('b', 'branches', None, _('annotate with branch names')), |
|
551 ('', 'dots', None, _('use dots for runs')), |
|
552 ('s', 'spaces', None, _('separate elements by spaces')), |
|
553 ], |
495 _('[OPTION]... [FILE [REV]...]'), |
554 _('[OPTION]... [FILE [REV]...]'), |
496 optionalrepo=True) |
555 optionalrepo=True, |
|
556 ) |
497 def debugdag(ui, repo, file_=None, *revs, **opts): |
557 def debugdag(ui, repo, file_=None, *revs, **opts): |
498 """format the changelog or an index DAG as a concise textual description |
558 """format the changelog or an index DAG as a concise textual description |
499 |
559 |
500 If you pass a revlog index, the revlog's DAG is emitted. If you list |
560 If you pass a revlog index, the revlog's DAG is emitted. If you list |
501 revision numbers, they get labeled in the output as rN. |
561 revision numbers, they get labeled in the output as rN. |
503 Otherwise, the changelog DAG of the current repo is emitted. |
563 Otherwise, the changelog DAG of the current repo is emitted. |
504 """ |
564 """ |
505 spaces = opts.get(r'spaces') |
565 spaces = opts.get(r'spaces') |
506 dots = opts.get(r'dots') |
566 dots = opts.get(r'dots') |
507 if file_: |
567 if file_: |
508 rlog = revlog.revlog(vfsmod.vfs(encoding.getcwd(), audit=False), |
568 rlog = revlog.revlog(vfsmod.vfs(encoding.getcwd(), audit=False), file_) |
509 file_) |
|
510 revs = set((int(r) for r in revs)) |
569 revs = set((int(r) for r in revs)) |
|
570 |
511 def events(): |
571 def events(): |
512 for r in rlog: |
572 for r in rlog: |
513 yield 'n', (r, list(p for p in rlog.parentrevs(r) |
573 yield 'n', (r, list(p for p in rlog.parentrevs(r) if p != -1)) |
514 if p != -1)) |
|
515 if r in revs: |
574 if r in revs: |
516 yield 'l', (r, "r%i" % r) |
575 yield 'l', (r, "r%i" % r) |
|
576 |
517 elif repo: |
577 elif repo: |
518 cl = repo.changelog |
578 cl = repo.changelog |
519 tags = opts.get(r'tags') |
579 tags = opts.get(r'tags') |
520 branches = opts.get(r'branches') |
580 branches = opts.get(r'branches') |
521 if tags: |
581 if tags: |
522 labels = {} |
582 labels = {} |
523 for l, n in repo.tags().items(): |
583 for l, n in repo.tags().items(): |
524 labels.setdefault(cl.rev(n), []).append(l) |
584 labels.setdefault(cl.rev(n), []).append(l) |
|
585 |
525 def events(): |
586 def events(): |
526 b = "default" |
587 b = "default" |
527 for r in cl: |
588 for r in cl: |
528 if branches: |
589 if branches: |
529 newb = cl.read(cl.node(r))[5]['branch'] |
590 newb = cl.read(cl.node(r))[5]['branch'] |
530 if newb != b: |
591 if newb != b: |
531 yield 'a', newb |
592 yield 'a', newb |
532 b = newb |
593 b = newb |
533 yield 'n', (r, list(p for p in cl.parentrevs(r) |
594 yield 'n', (r, list(p for p in cl.parentrevs(r) if p != -1)) |
534 if p != -1)) |
|
535 if tags: |
595 if tags: |
536 ls = labels.get(r) |
596 ls = labels.get(r) |
537 if ls: |
597 if ls: |
538 for l in ls: |
598 for l in ls: |
539 yield 'l', (r, l) |
599 yield 'l', (r, l) |
|
600 |
540 else: |
601 else: |
541 raise error.Abort(_('need repo for changelog dag')) |
602 raise error.Abort(_('need repo for changelog dag')) |
542 |
603 |
543 for line in dagparser.dagtextlines(events(), |
604 for line in dagparser.dagtextlines( |
544 addspaces=spaces, |
605 events(), |
545 wraplabels=True, |
606 addspaces=spaces, |
546 wrapannotations=True, |
607 wraplabels=True, |
547 wrapnonlinear=dots, |
608 wrapannotations=True, |
548 usedots=dots, |
609 wrapnonlinear=dots, |
549 maxlinewidth=70): |
610 usedots=dots, |
|
611 maxlinewidth=70, |
|
612 ): |
550 ui.write(line) |
613 ui.write(line) |
551 ui.write("\n") |
614 ui.write("\n") |
|
615 |
552 |
616 |
553 @command('debugdata', cmdutil.debugrevlogopts, _('-c|-m|FILE REV')) |
617 @command('debugdata', cmdutil.debugrevlogopts, _('-c|-m|FILE REV')) |
554 def debugdata(ui, repo, file_, rev=None, **opts): |
618 def debugdata(ui, repo, file_, rev=None, **opts): |
555 """dump the contents of a data file revision""" |
619 """dump the contents of a data file revision""" |
556 opts = pycompat.byteskwargs(opts) |
620 opts = pycompat.byteskwargs(opts) |
564 try: |
628 try: |
565 ui.write(r.rawdata(r.lookup(rev))) |
629 ui.write(r.rawdata(r.lookup(rev))) |
566 except KeyError: |
630 except KeyError: |
567 raise error.Abort(_('invalid revision identifier %s') % rev) |
631 raise error.Abort(_('invalid revision identifier %s') % rev) |
568 |
632 |
569 @command('debugdate', |
633 |
|
634 @command( |
|
635 'debugdate', |
570 [('e', 'extended', None, _('try extended date formats'))], |
636 [('e', 'extended', None, _('try extended date formats'))], |
571 _('[-e] DATE [RANGE]'), |
637 _('[-e] DATE [RANGE]'), |
572 norepo=True, optionalrepo=True) |
638 norepo=True, |
|
639 optionalrepo=True, |
|
640 ) |
573 def debugdate(ui, date, range=None, **opts): |
641 def debugdate(ui, date, range=None, **opts): |
574 """parse and display a date""" |
642 """parse and display a date""" |
575 if opts[r"extended"]: |
643 if opts[r"extended"]: |
576 d = dateutil.parsedate(date, util.extendeddateformats) |
644 d = dateutil.parsedate(date, util.extendeddateformats) |
577 else: |
645 else: |
578 d = dateutil.parsedate(date) |
646 d = dateutil.parsedate(date) |
579 ui.write(("internal: %d %d\n") % d) |
647 ui.write("internal: %d %d\n" % d) |
580 ui.write(("standard: %s\n") % dateutil.datestr(d)) |
648 ui.write("standard: %s\n" % dateutil.datestr(d)) |
581 if range: |
649 if range: |
582 m = dateutil.matchdate(range) |
650 m = dateutil.matchdate(range) |
583 ui.write(("match: %s\n") % m(d[0])) |
651 ui.write("match: %s\n" % m(d[0])) |
584 |
652 |
585 @command('debugdeltachain', |
653 |
|
654 @command( |
|
655 'debugdeltachain', |
586 cmdutil.debugrevlogopts + cmdutil.formatteropts, |
656 cmdutil.debugrevlogopts + cmdutil.formatteropts, |
587 _('-c|-m|FILE'), |
657 _('-c|-m|FILE'), |
588 optionalrepo=True) |
658 optionalrepo=True, |
|
659 ) |
589 def debugdeltachain(ui, repo, file_=None, **opts): |
660 def debugdeltachain(ui, repo, file_=None, **opts): |
590 """dump information about delta chains in a revlog |
661 """dump information about delta chains in a revlog |
591 |
662 |
592 Output can be templatized. Available template keywords are: |
663 Output can be templatized. Available template keywords are: |
593 |
664 |
722 if readsize: |
813 if readsize: |
723 readdensity = float(chainsize) / float(readsize) |
814 readdensity = float(chainsize) / float(readsize) |
724 else: |
815 else: |
725 readdensity = 1 |
816 readdensity = 1 |
726 |
817 |
727 fm.write('readsize largestblock readdensity srchunks', |
818 fm.write( |
728 ' %10d %10d %9.5f %8d', |
819 'readsize largestblock readdensity srchunks', |
729 readsize, largestblock, readdensity, srchunks, |
820 ' %10d %10d %9.5f %8d', |
730 readsize=readsize, largestblock=largestblock, |
821 readsize, |
731 readdensity=readdensity, srchunks=srchunks) |
822 largestblock, |
|
823 readdensity, |
|
824 srchunks, |
|
825 readsize=readsize, |
|
826 largestblock=largestblock, |
|
827 readdensity=readdensity, |
|
828 srchunks=srchunks, |
|
829 ) |
732 |
830 |
733 fm.plain('\n') |
831 fm.plain('\n') |
734 |
832 |
735 fm.end() |
833 fm.end() |
736 |
834 |
737 @command('debugdirstate|debugstate', |
835 |
738 [('', 'nodates', None, _('do not display the saved mtime (DEPRECATED)')), |
836 @command( |
739 ('', 'dates', True, _('display the saved mtime')), |
837 'debugdirstate|debugstate', |
740 ('', 'datesort', None, _('sort by saved mtime'))], |
838 [ |
741 _('[OPTION]...')) |
839 ('', 'nodates', None, _('do not display the saved mtime (DEPRECATED)')), |
|
840 ('', 'dates', True, _('display the saved mtime')), |
|
841 ('', 'datesort', None, _('sort by saved mtime')), |
|
842 ], |
|
843 _('[OPTION]...'), |
|
844 ) |
742 def debugstate(ui, repo, **opts): |
845 def debugstate(ui, repo, **opts): |
743 """show the contents of the current dirstate""" |
846 """show the contents of the current dirstate""" |
744 |
847 |
745 nodates = not opts[r'dates'] |
848 nodates = not opts[r'dates'] |
746 if opts.get(r'nodates') is not None: |
849 if opts.get(r'nodates') is not None: |
747 nodates = True |
850 nodates = True |
748 datesort = opts.get(r'datesort') |
851 datesort = opts.get(r'datesort') |
749 |
852 |
750 if datesort: |
853 if datesort: |
751 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename |
854 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename |
752 else: |
855 else: |
753 keyfunc = None # sort by filename |
856 keyfunc = None # sort by filename |
754 for file_, ent in sorted(repo.dirstate.iteritems(), key=keyfunc): |
857 for file_, ent in sorted(repo.dirstate.iteritems(), key=keyfunc): |
755 if ent[3] == -1: |
858 if ent[3] == -1: |
756 timestr = 'unset ' |
859 timestr = 'unset ' |
757 elif nodates: |
860 elif nodates: |
758 timestr = 'set ' |
861 timestr = 'set ' |
759 else: |
862 else: |
760 timestr = time.strftime(r"%Y-%m-%d %H:%M:%S ", |
863 timestr = time.strftime( |
761 time.localtime(ent[3])) |
864 r"%Y-%m-%d %H:%M:%S ", time.localtime(ent[3]) |
|
865 ) |
762 timestr = encoding.strtolocal(timestr) |
866 timestr = encoding.strtolocal(timestr) |
763 if ent[1] & 0o20000: |
867 if ent[1] & 0o20000: |
764 mode = 'lnk' |
868 mode = 'lnk' |
765 else: |
869 else: |
766 mode = '%3o' % (ent[1] & 0o777 & ~util.umask) |
870 mode = '%3o' % (ent[1] & 0o777 & ~util.umask) |
767 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_)) |
871 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_)) |
768 for f in repo.dirstate.copies(): |
872 for f in repo.dirstate.copies(): |
769 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f)) |
873 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f)) |
770 |
874 |
771 @command('debugdiscovery', |
875 |
772 [('', 'old', None, _('use old-style discovery')), |
876 @command( |
773 ('', 'nonheads', None, |
877 'debugdiscovery', |
774 _('use old-style discovery with non-heads included')), |
878 [ |
775 ('', 'rev', [], 'restrict discovery to this set of revs'), |
879 ('', 'old', None, _('use old-style discovery')), |
776 ('', 'seed', '12323', 'specify the random seed use for discovery'), |
880 ( |
777 ] + cmdutil.remoteopts, |
881 '', |
778 _('[--rev REV] [OTHER]')) |
882 'nonheads', |
|
883 None, |
|
884 _('use old-style discovery with non-heads included'), |
|
885 ), |
|
886 ('', 'rev', [], 'restrict discovery to this set of revs'), |
|
887 ('', 'seed', '12323', 'specify the random seed use for discovery'), |
|
888 ] |
|
889 + cmdutil.remoteopts, |
|
890 _('[--rev REV] [OTHER]'), |
|
891 ) |
779 def debugdiscovery(ui, repo, remoteurl="default", **opts): |
892 def debugdiscovery(ui, repo, remoteurl="default", **opts): |
780 """runs the changeset discovery protocol in isolation""" |
893 """runs the changeset discovery protocol in isolation""" |
781 opts = pycompat.byteskwargs(opts) |
894 opts = pycompat.byteskwargs(opts) |
782 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl)) |
895 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl)) |
783 remote = hg.peer(repo, opts, remoteurl) |
896 remote = hg.peer(repo, opts, remoteurl) |
784 ui.status(_('comparing with %s\n') % util.hidepassword(remoteurl)) |
897 ui.status(_('comparing with %s\n') % util.hidepassword(remoteurl)) |
785 |
898 |
786 # make sure tests are repeatable |
899 # make sure tests are repeatable |
787 random.seed(int(opts['seed'])) |
900 random.seed(int(opts['seed'])) |
788 |
901 |
789 |
|
790 |
|
791 if opts.get('old'): |
902 if opts.get('old'): |
|
903 |
792 def doit(pushedrevs, remoteheads, remote=remote): |
904 def doit(pushedrevs, remoteheads, remote=remote): |
793 if not util.safehasattr(remote, 'branches'): |
905 if not util.safehasattr(remote, 'branches'): |
794 # enable in-client legacy support |
906 # enable in-client legacy support |
795 remote = localrepo.locallegacypeer(remote.local()) |
907 remote = localrepo.locallegacypeer(remote.local()) |
796 common, _in, hds = treediscovery.findcommonincoming(repo, remote, |
908 common, _in, hds = treediscovery.findcommonincoming( |
797 force=True) |
909 repo, remote, force=True |
|
910 ) |
798 common = set(common) |
911 common = set(common) |
799 if not opts.get('nonheads'): |
912 if not opts.get('nonheads'): |
800 ui.write(("unpruned common: %s\n") % |
913 ui.write( |
801 " ".join(sorted(short(n) for n in common))) |
914 "unpruned common: %s\n" |
|
915 % " ".join(sorted(short(n) for n in common)) |
|
916 ) |
802 |
917 |
803 clnode = repo.changelog.node |
918 clnode = repo.changelog.node |
804 common = repo.revs('heads(::%ln)', common) |
919 common = repo.revs('heads(::%ln)', common) |
805 common = {clnode(r) for r in common} |
920 common = {clnode(r) for r in common} |
806 return common, hds |
921 return common, hds |
|
922 |
807 else: |
923 else: |
|
924 |
808 def doit(pushedrevs, remoteheads, remote=remote): |
925 def doit(pushedrevs, remoteheads, remote=remote): |
809 nodes = None |
926 nodes = None |
810 if pushedrevs: |
927 if pushedrevs: |
811 revs = scmutil.revrange(repo, pushedrevs) |
928 revs = scmutil.revrange(repo, pushedrevs) |
812 nodes = [repo[r].node() for r in revs] |
929 nodes = [repo[r].node() for r in revs] |
813 common, any, hds = setdiscovery.findcommonheads(ui, repo, remote, |
930 common, any, hds = setdiscovery.findcommonheads( |
814 ancestorsof=nodes) |
931 ui, repo, remote, ancestorsof=nodes |
|
932 ) |
815 return common, hds |
933 return common, hds |
816 |
934 |
817 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches, revs=None) |
935 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches, revs=None) |
818 localrevs = opts['rev'] |
936 localrevs = opts['rev'] |
819 with util.timedcm('debug-discovery') as t: |
937 with util.timedcm('debug-discovery') as t: |
837 data['nb-revs'] = len(repo.revs('all()')) |
955 data['nb-revs'] = len(repo.revs('all()')) |
838 data['nb-revs-common'] = len(repo.revs('::%ln', common)) |
956 data['nb-revs-common'] = len(repo.revs('::%ln', common)) |
839 data['nb-revs-missing'] = data['nb-revs'] - data['nb-revs-common'] |
957 data['nb-revs-missing'] = data['nb-revs'] - data['nb-revs-common'] |
840 |
958 |
841 # display discovery summary |
959 # display discovery summary |
842 ui.write(("elapsed time: %(elapsed)f seconds\n") % data) |
960 ui.write("elapsed time: %(elapsed)f seconds\n" % data) |
843 ui.write(("heads summary:\n")) |
961 ui.write("heads summary:\n") |
844 ui.write((" total common heads: %(nb-common)9d\n") % data) |
962 ui.write(" total common heads: %(nb-common)9d\n" % data) |
845 ui.write((" also local heads: %(nb-common-local)9d\n") % data) |
963 ui.write(" also local heads: %(nb-common-local)9d\n" % data) |
846 ui.write((" also remote heads: %(nb-common-remote)9d\n") % data) |
964 ui.write(" also remote heads: %(nb-common-remote)9d\n" % data) |
847 ui.write((" both: %(nb-common-both)9d\n") % data) |
965 ui.write(" both: %(nb-common-both)9d\n" % data) |
848 ui.write((" local heads: %(nb-local)9d\n") % data) |
966 ui.write(" local heads: %(nb-local)9d\n" % data) |
849 ui.write((" common: %(nb-common-local)9d\n") % data) |
967 ui.write(" common: %(nb-common-local)9d\n" % data) |
850 ui.write((" missing: %(nb-local-missing)9d\n") % data) |
968 ui.write(" missing: %(nb-local-missing)9d\n" % data) |
851 ui.write((" remote heads: %(nb-remote)9d\n") % data) |
969 ui.write(" remote heads: %(nb-remote)9d\n" % data) |
852 ui.write((" common: %(nb-common-remote)9d\n") % data) |
970 ui.write(" common: %(nb-common-remote)9d\n" % data) |
853 ui.write((" unknown: %(nb-remote-unknown)9d\n") % data) |
971 ui.write(" unknown: %(nb-remote-unknown)9d\n" % data) |
854 ui.write(("local changesets: %(nb-revs)9d\n") % data) |
972 ui.write("local changesets: %(nb-revs)9d\n" % data) |
855 ui.write((" common: %(nb-revs-common)9d\n") % data) |
973 ui.write(" common: %(nb-revs-common)9d\n" % data) |
856 ui.write((" missing: %(nb-revs-missing)9d\n") % data) |
974 ui.write(" missing: %(nb-revs-missing)9d\n" % data) |
857 |
975 |
858 if ui.verbose: |
976 if ui.verbose: |
859 ui.write(("common heads: %s\n") % |
977 ui.write( |
860 " ".join(sorted(short(n) for n in common))) |
978 "common heads: %s\n" % " ".join(sorted(short(n) for n in common)) |
|
979 ) |
|
980 |
861 |
981 |
862 _chunksize = 4 << 10 |
982 _chunksize = 4 << 10 |
863 |
983 |
864 @command('debugdownload', |
984 |
865 [ |
985 @command('debugdownload', [('o', 'output', '', _('path')),], optionalrepo=True) |
866 ('o', 'output', '', _('path')), |
|
867 ], |
|
868 optionalrepo=True) |
|
869 def debugdownload(ui, repo, url, output=None, **opts): |
986 def debugdownload(ui, repo, url, output=None, **opts): |
870 """download a resource using Mercurial logic and config |
987 """download a resource using Mercurial logic and config |
871 """ |
988 """ |
872 fh = urlmod.open(ui, url, output) |
989 fh = urlmod.open(ui, url, output) |
873 |
990 |
911 fm.plain(_(' (untested!)\n')) |
1029 fm.plain(_(' (untested!)\n')) |
912 else: |
1030 else: |
913 lasttestedversion = exttestedwith[-1] |
1031 lasttestedversion = exttestedwith[-1] |
914 fm.plain(' (%s!)\n' % lasttestedversion) |
1032 fm.plain(' (%s!)\n' % lasttestedversion) |
915 |
1033 |
916 fm.condwrite(ui.verbose and extsource, 'source', |
1034 fm.condwrite( |
917 _(' location: %s\n'), extsource or "") |
1035 ui.verbose and extsource, |
|
1036 'source', |
|
1037 _(' location: %s\n'), |
|
1038 extsource or "", |
|
1039 ) |
918 |
1040 |
919 if ui.verbose: |
1041 if ui.verbose: |
920 fm.plain(_(' bundled: %s\n') % ['no', 'yes'][isinternal]) |
1042 fm.plain(_(' bundled: %s\n') % ['no', 'yes'][isinternal]) |
921 fm.data(bundled=isinternal) |
1043 fm.data(bundled=isinternal) |
922 |
1044 |
923 fm.condwrite(ui.verbose and exttestedwith, 'testedwith', |
1045 fm.condwrite( |
924 _(' tested with: %s\n'), |
1046 ui.verbose and exttestedwith, |
925 fm.formatlist(exttestedwith, name='ver')) |
1047 'testedwith', |
926 |
1048 _(' tested with: %s\n'), |
927 fm.condwrite(ui.verbose and extbuglink, 'buglink', |
1049 fm.formatlist(exttestedwith, name='ver'), |
928 _(' bug reporting: %s\n'), extbuglink or "") |
1050 ) |
|
1051 |
|
1052 fm.condwrite( |
|
1053 ui.verbose and extbuglink, |
|
1054 'buglink', |
|
1055 _(' bug reporting: %s\n'), |
|
1056 extbuglink or "", |
|
1057 ) |
929 |
1058 |
930 fm.end() |
1059 fm.end() |
931 |
1060 |
932 @command('debugfileset', |
1061 |
933 [('r', 'rev', '', _('apply the filespec on this revision'), _('REV')), |
1062 @command( |
934 ('', 'all-files', False, |
1063 'debugfileset', |
935 _('test files from all revisions and working directory')), |
1064 [ |
936 ('s', 'show-matcher', None, |
1065 ('r', 'rev', '', _('apply the filespec on this revision'), _('REV')), |
937 _('print internal representation of matcher')), |
1066 ( |
938 ('p', 'show-stage', [], |
1067 '', |
939 _('print parsed tree at the given stage'), _('NAME'))], |
1068 'all-files', |
940 _('[-r REV] [--all-files] [OPTION]... FILESPEC')) |
1069 False, |
|
1070 _('test files from all revisions and working directory'), |
|
1071 ), |
|
1072 ( |
|
1073 's', |
|
1074 'show-matcher', |
|
1075 None, |
|
1076 _('print internal representation of matcher'), |
|
1077 ), |
|
1078 ( |
|
1079 'p', |
|
1080 'show-stage', |
|
1081 [], |
|
1082 _('print parsed tree at the given stage'), |
|
1083 _('NAME'), |
|
1084 ), |
|
1085 ], |
|
1086 _('[-r REV] [--all-files] [OPTION]... FILESPEC'), |
|
1087 ) |
941 def debugfileset(ui, repo, expr, **opts): |
1088 def debugfileset(ui, repo, expr, **opts): |
942 '''parse and apply a fileset specification''' |
1089 '''parse and apply a fileset specification''' |
943 from . import fileset |
1090 from . import fileset |
944 fileset.symbols # force import of fileset so we have predicates to optimize |
1091 |
|
1092 fileset.symbols # force import of fileset so we have predicates to optimize |
945 opts = pycompat.byteskwargs(opts) |
1093 opts = pycompat.byteskwargs(opts) |
946 ctx = scmutil.revsingle(repo, opts.get('rev'), None) |
1094 ctx = scmutil.revsingle(repo, opts.get('rev'), None) |
947 |
1095 |
948 stages = [ |
1096 stages = [ |
949 ('parsed', pycompat.identity), |
1097 ('parsed', pycompat.identity), |
967 tree = filesetlang.parse(expr) |
1115 tree = filesetlang.parse(expr) |
968 for n, f in stages: |
1116 for n, f in stages: |
969 tree = f(tree) |
1117 tree = f(tree) |
970 if n in showalways: |
1118 if n in showalways: |
971 if opts['show_stage'] or n != 'parsed': |
1119 if opts['show_stage'] or n != 'parsed': |
972 ui.write(("* %s:\n") % n) |
1120 ui.write("* %s:\n" % n) |
973 ui.write(filesetlang.prettyformat(tree), "\n") |
1121 ui.write(filesetlang.prettyformat(tree), "\n") |
974 |
1122 |
975 files = set() |
1123 files = set() |
976 if opts['all_files']: |
1124 if opts['all_files']: |
977 for r in repo: |
1125 for r in repo: |
978 c = repo[r] |
1126 c = repo[r] |
979 files.update(c.files()) |
1127 files.update(c.files()) |
980 files.update(c.substate) |
1128 files.update(c.substate) |
981 if opts['all_files'] or ctx.rev() is None: |
1129 if opts['all_files'] or ctx.rev() is None: |
982 wctx = repo[None] |
1130 wctx = repo[None] |
983 files.update(repo.dirstate.walk(scmutil.matchall(repo), |
1131 files.update( |
984 subrepos=list(wctx.substate), |
1132 repo.dirstate.walk( |
985 unknown=True, ignored=True)) |
1133 scmutil.matchall(repo), |
|
1134 subrepos=list(wctx.substate), |
|
1135 unknown=True, |
|
1136 ignored=True, |
|
1137 ) |
|
1138 ) |
986 files.update(wctx.substate) |
1139 files.update(wctx.substate) |
987 else: |
1140 else: |
988 files.update(ctx.files()) |
1141 files.update(ctx.files()) |
989 files.update(ctx.substate) |
1142 files.update(ctx.substate) |
990 |
1143 |
991 m = ctx.matchfileset(expr) |
1144 m = ctx.matchfileset(expr) |
992 if opts['show_matcher'] or (opts['show_matcher'] is None and ui.verbose): |
1145 if opts['show_matcher'] or (opts['show_matcher'] is None and ui.verbose): |
993 ui.write(('* matcher:\n'), stringutil.prettyrepr(m), '\n') |
1146 ui.write('* matcher:\n', stringutil.prettyrepr(m), '\n') |
994 for f in sorted(files): |
1147 for f in sorted(files): |
995 if not m(f): |
1148 if not m(f): |
996 continue |
1149 continue |
997 ui.write("%s\n" % f) |
1150 ui.write("%s\n" % f) |
998 |
1151 |
999 @command('debugformat', |
1152 |
1000 [] + cmdutil.formatteropts) |
1153 @command('debugformat', [] + cmdutil.formatteropts) |
1001 def debugformat(ui, repo, **opts): |
1154 def debugformat(ui, repo, **opts): |
1002 """display format information about the current repository |
1155 """display format information about the current repository |
1003 |
1156 |
1004 Use --verbose to get extra information about current config value and |
1157 Use --verbose to get extra information about current config value and |
1005 Mercurial default.""" |
1158 Mercurial default.""" |
1041 repolabel = 'formatvariant.repo.mismatchdefault' |
1196 repolabel = 'formatvariant.repo.mismatchdefault' |
1042 else: |
1197 else: |
1043 namelabel = 'formatvariant.name.uptodate' |
1198 namelabel = 'formatvariant.name.uptodate' |
1044 repolabel = 'formatvariant.repo.uptodate' |
1199 repolabel = 'formatvariant.repo.uptodate' |
1045 |
1200 |
1046 fm.write('name', makeformatname(fv.name), fv.name, |
1201 fm.write('name', makeformatname(fv.name), fv.name, label=namelabel) |
1047 label=namelabel) |
1202 fm.write('repo', ' %3s', formatvalue(repovalue), label=repolabel) |
1048 fm.write('repo', ' %3s', formatvalue(repovalue), |
|
1049 label=repolabel) |
|
1050 if fv.default != configvalue: |
1203 if fv.default != configvalue: |
1051 configlabel = 'formatvariant.config.special' |
1204 configlabel = 'formatvariant.config.special' |
1052 else: |
1205 else: |
1053 configlabel = 'formatvariant.config.default' |
1206 configlabel = 'formatvariant.config.default' |
1054 fm.condwrite(ui.verbose, 'config', ' %6s', formatvalue(configvalue), |
1207 fm.condwrite( |
1055 label=configlabel) |
1208 ui.verbose, |
1056 fm.condwrite(ui.verbose, 'default', ' %7s', formatvalue(fv.default), |
1209 'config', |
1057 label='formatvariant.default') |
1210 ' %6s', |
|
1211 formatvalue(configvalue), |
|
1212 label=configlabel, |
|
1213 ) |
|
1214 fm.condwrite( |
|
1215 ui.verbose, |
|
1216 'default', |
|
1217 ' %7s', |
|
1218 formatvalue(fv.default), |
|
1219 label='formatvariant.default', |
|
1220 ) |
1058 fm.plain('\n') |
1221 fm.plain('\n') |
1059 fm.end() |
1222 fm.end() |
|
1223 |
1060 |
1224 |
1061 @command('debugfsinfo', [], _('[PATH]'), norepo=True) |
1225 @command('debugfsinfo', [], _('[PATH]'), norepo=True) |
1062 def debugfsinfo(ui, path="."): |
1226 def debugfsinfo(ui, path="."): |
1063 """show information detected about current filesystem""" |
1227 """show information detected about current filesystem""" |
1064 ui.write(('path: %s\n') % path) |
1228 ui.write('path: %s\n' % path) |
1065 ui.write(('mounted on: %s\n') % (util.getfsmountpoint(path) or '(unknown)')) |
1229 ui.write('mounted on: %s\n' % (util.getfsmountpoint(path) or '(unknown)')) |
1066 ui.write(('exec: %s\n') % (util.checkexec(path) and 'yes' or 'no')) |
1230 ui.write('exec: %s\n' % (util.checkexec(path) and 'yes' or 'no')) |
1067 ui.write(('fstype: %s\n') % (util.getfstype(path) or '(unknown)')) |
1231 ui.write('fstype: %s\n' % (util.getfstype(path) or '(unknown)')) |
1068 ui.write(('symlink: %s\n') % (util.checklink(path) and 'yes' or 'no')) |
1232 ui.write('symlink: %s\n' % (util.checklink(path) and 'yes' or 'no')) |
1069 ui.write(('hardlink: %s\n') % (util.checknlink(path) and 'yes' or 'no')) |
1233 ui.write('hardlink: %s\n' % (util.checknlink(path) and 'yes' or 'no')) |
1070 casesensitive = '(unknown)' |
1234 casesensitive = '(unknown)' |
1071 try: |
1235 try: |
1072 with pycompat.namedtempfile(prefix='.debugfsinfo', dir=path) as f: |
1236 with pycompat.namedtempfile(prefix='.debugfsinfo', dir=path) as f: |
1073 casesensitive = util.fscasesensitive(f.name) and 'yes' or 'no' |
1237 casesensitive = util.fscasesensitive(f.name) and 'yes' or 'no' |
1074 except OSError: |
1238 except OSError: |
1075 pass |
1239 pass |
1076 ui.write(('case-sensitive: %s\n') % casesensitive) |
1240 ui.write('case-sensitive: %s\n' % casesensitive) |
1077 |
1241 |
1078 @command('debuggetbundle', |
1242 |
1079 [('H', 'head', [], _('id of head node'), _('ID')), |
1243 @command( |
1080 ('C', 'common', [], _('id of common node'), _('ID')), |
1244 'debuggetbundle', |
1081 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE'))], |
1245 [ |
|
1246 ('H', 'head', [], _('id of head node'), _('ID')), |
|
1247 ('C', 'common', [], _('id of common node'), _('ID')), |
|
1248 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')), |
|
1249 ], |
1082 _('REPO FILE [-H|-C ID]...'), |
1250 _('REPO FILE [-H|-C ID]...'), |
1083 norepo=True) |
1251 norepo=True, |
|
1252 ) |
1084 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts): |
1253 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts): |
1085 """retrieves a bundle from a repo |
1254 """retrieves a bundle from a repo |
1086 |
1255 |
1087 Every ID must be a full-length hex node id string. Saves the bundle to the |
1256 Every ID must be a full-length hex node id string. Saves the bundle to the |
1088 given file. |
1257 given file. |
1187 fm.write(b'p2', '%s', shortfn(parents[1])) |
1370 fm.write(b'p2', '%s', shortfn(parents[1])) |
1188 fm.plain(b'\n') |
1371 fm.plain(b'\n') |
1189 |
1372 |
1190 fm.end() |
1373 fm.end() |
1191 |
1374 |
1192 @command('debugindexdot', cmdutil.debugrevlogopts, |
1375 |
1193 _('-c|-m|FILE'), optionalrepo=True) |
1376 @command( |
|
1377 'debugindexdot', cmdutil.debugrevlogopts, _('-c|-m|FILE'), optionalrepo=True |
|
1378 ) |
1194 def debugindexdot(ui, repo, file_=None, **opts): |
1379 def debugindexdot(ui, repo, file_=None, **opts): |
1195 """dump an index DAG as a graphviz dot file""" |
1380 """dump an index DAG as a graphviz dot file""" |
1196 opts = pycompat.byteskwargs(opts) |
1381 opts = pycompat.byteskwargs(opts) |
1197 r = cmdutil.openstorage(repo, 'debugindexdot', file_, opts) |
1382 r = cmdutil.openstorage(repo, 'debugindexdot', file_, opts) |
1198 ui.write(("digraph G {\n")) |
1383 ui.write("digraph G {\n") |
1199 for i in r: |
1384 for i in r: |
1200 node = r.node(i) |
1385 node = r.node(i) |
1201 pp = r.parents(node) |
1386 pp = r.parents(node) |
1202 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i)) |
1387 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i)) |
1203 if pp[1] != nullid: |
1388 if pp[1] != nullid: |
1204 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i)) |
1389 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i)) |
1205 ui.write("}\n") |
1390 ui.write("}\n") |
|
1391 |
1206 |
1392 |
1207 @command('debugindexstats', []) |
1393 @command('debugindexstats', []) |
1208 def debugindexstats(ui, repo): |
1394 def debugindexstats(ui, repo): |
1209 """show stats related to the changelog index""" |
1395 """show stats related to the changelog index""" |
1210 repo.changelog.shortest(nullid, 1) |
1396 repo.changelog.shortest(nullid, 1) |
1233 try: |
1420 try: |
1234 codecs.lookup(pycompat.sysstr(encoding.encoding)) |
1421 codecs.lookup(pycompat.sysstr(encoding.encoding)) |
1235 except LookupError as inst: |
1422 except LookupError as inst: |
1236 err = stringutil.forcebytestr(inst) |
1423 err = stringutil.forcebytestr(inst) |
1237 problems += 1 |
1424 problems += 1 |
1238 fm.condwrite(err, 'encodingerror', _(" %s\n" |
1425 fm.condwrite( |
1239 " (check that your locale is properly set)\n"), err) |
1426 err, |
|
1427 'encodingerror', |
|
1428 _(" %s\n" " (check that your locale is properly set)\n"), |
|
1429 err, |
|
1430 ) |
1240 |
1431 |
1241 # Python |
1432 # Python |
1242 fm.write('pythonexe', _("checking Python executable (%s)\n"), |
1433 fm.write( |
1243 pycompat.sysexecutable or _("unknown")) |
1434 'pythonexe', |
1244 fm.write('pythonver', _("checking Python version (%s)\n"), |
1435 _("checking Python executable (%s)\n"), |
1245 ("%d.%d.%d" % sys.version_info[:3])) |
1436 pycompat.sysexecutable or _("unknown"), |
1246 fm.write('pythonlib', _("checking Python lib (%s)...\n"), |
1437 ) |
1247 os.path.dirname(pycompat.fsencode(os.__file__))) |
1438 fm.write( |
|
1439 'pythonver', |
|
1440 _("checking Python version (%s)\n"), |
|
1441 ("%d.%d.%d" % sys.version_info[:3]), |
|
1442 ) |
|
1443 fm.write( |
|
1444 'pythonlib', |
|
1445 _("checking Python lib (%s)...\n"), |
|
1446 os.path.dirname(pycompat.fsencode(os.__file__)), |
|
1447 ) |
1248 |
1448 |
1249 security = set(sslutil.supportedprotocols) |
1449 security = set(sslutil.supportedprotocols) |
1250 if sslutil.hassni: |
1450 if sslutil.hassni: |
1251 security.add('sni') |
1451 security.add('sni') |
1252 |
1452 |
1253 fm.write('pythonsecurity', _("checking Python security support (%s)\n"), |
1453 fm.write( |
1254 fm.formatlist(sorted(security), name='protocol', |
1454 'pythonsecurity', |
1255 fmt='%s', sep=',')) |
1455 _("checking Python security support (%s)\n"), |
|
1456 fm.formatlist(sorted(security), name='protocol', fmt='%s', sep=','), |
|
1457 ) |
1256 |
1458 |
1257 # These are warnings, not errors. So don't increment problem count. This |
1459 # These are warnings, not errors. So don't increment problem count. This |
1258 # may change in the future. |
1460 # may change in the future. |
1259 if 'tls1.2' not in security: |
1461 if 'tls1.2' not in security: |
1260 fm.plain(_(' TLS 1.2 not supported by Python install; ' |
1462 fm.plain( |
1261 'network connections lack modern security\n')) |
1463 _( |
|
1464 ' TLS 1.2 not supported by Python install; ' |
|
1465 'network connections lack modern security\n' |
|
1466 ) |
|
1467 ) |
1262 if 'sni' not in security: |
1468 if 'sni' not in security: |
1263 fm.plain(_(' SNI not supported by Python install; may have ' |
1469 fm.plain( |
1264 'connectivity issues with some servers\n')) |
1470 _( |
|
1471 ' SNI not supported by Python install; may have ' |
|
1472 'connectivity issues with some servers\n' |
|
1473 ) |
|
1474 ) |
1265 |
1475 |
1266 # TODO print CA cert info |
1476 # TODO print CA cert info |
1267 |
1477 |
1268 # hg version |
1478 # hg version |
1269 hgver = util.version() |
1479 hgver = util.version() |
1270 fm.write('hgver', _("checking Mercurial version (%s)\n"), |
1480 fm.write( |
1271 hgver.split('+')[0]) |
1481 'hgver', _("checking Mercurial version (%s)\n"), hgver.split('+')[0] |
1272 fm.write('hgverextra', _("checking Mercurial custom build (%s)\n"), |
1482 ) |
1273 '+'.join(hgver.split('+')[1:])) |
1483 fm.write( |
|
1484 'hgverextra', |
|
1485 _("checking Mercurial custom build (%s)\n"), |
|
1486 '+'.join(hgver.split('+')[1:]), |
|
1487 ) |
1274 |
1488 |
1275 # compiled modules |
1489 # compiled modules |
1276 fm.write('hgmodulepolicy', _("checking module policy (%s)\n"), |
1490 fm.write( |
1277 policy.policy) |
1491 'hgmodulepolicy', _("checking module policy (%s)\n"), policy.policy |
1278 fm.write('hgmodules', _("checking installed modules (%s)...\n"), |
1492 ) |
1279 os.path.dirname(pycompat.fsencode(__file__))) |
1493 fm.write( |
|
1494 'hgmodules', |
|
1495 _("checking installed modules (%s)...\n"), |
|
1496 os.path.dirname(pycompat.fsencode(__file__)), |
|
1497 ) |
1280 |
1498 |
1281 rustandc = policy.policy in ('rust+c', 'rust+c-allow') |
1499 rustandc = policy.policy in ('rust+c', 'rust+c-allow') |
1282 rustext = rustandc # for now, that's the only case |
1500 rustext = rustandc # for now, that's the only case |
1283 cext = policy.policy in ('c', 'allow') or rustandc |
1501 cext = policy.policy in ('c', 'allow') or rustandc |
1284 nopure = cext or rustext |
1502 nopure = cext or rustext |
1290 base85, |
1508 base85, |
1291 bdiff, |
1509 bdiff, |
1292 mpatch, |
1510 mpatch, |
1293 osutil, |
1511 osutil, |
1294 ) |
1512 ) |
|
1513 |
1295 # quiet pyflakes |
1514 # quiet pyflakes |
1296 dir(bdiff), dir(mpatch), dir(base85), dir(osutil) |
1515 dir(bdiff), dir(mpatch), dir(base85), dir(osutil) |
1297 if rustext: |
1516 if rustext: |
1298 from .rustext import ( |
1517 from .rustext import ( |
1299 ancestor, |
1518 ancestor, |
1300 dirstate, |
1519 dirstate, |
1301 ) |
1520 ) |
1302 dir(ancestor), dir(dirstate) # quiet pyflakes |
1521 |
|
1522 dir(ancestor), dir(dirstate) # quiet pyflakes |
1303 except Exception as inst: |
1523 except Exception as inst: |
1304 err = stringutil.forcebytestr(inst) |
1524 err = stringutil.forcebytestr(inst) |
1305 problems += 1 |
1525 problems += 1 |
1306 fm.condwrite(err, 'extensionserror', " %s\n", err) |
1526 fm.condwrite(err, 'extensionserror', " %s\n", err) |
1307 |
1527 |
1308 compengines = util.compengines._engines.values() |
1528 compengines = util.compengines._engines.values() |
1309 fm.write('compengines', _('checking registered compression engines (%s)\n'), |
1529 fm.write( |
1310 fm.formatlist(sorted(e.name() for e in compengines), |
1530 'compengines', |
1311 name='compengine', fmt='%s', sep=', ')) |
1531 _('checking registered compression engines (%s)\n'), |
1312 fm.write('compenginesavail', _('checking available compression engines ' |
1532 fm.formatlist( |
1313 '(%s)\n'), |
1533 sorted(e.name() for e in compengines), |
1314 fm.formatlist(sorted(e.name() for e in compengines |
1534 name='compengine', |
1315 if e.available()), |
1535 fmt='%s', |
1316 name='compengine', fmt='%s', sep=', ')) |
1536 sep=', ', |
|
1537 ), |
|
1538 ) |
|
1539 fm.write( |
|
1540 'compenginesavail', |
|
1541 _('checking available compression engines ' '(%s)\n'), |
|
1542 fm.formatlist( |
|
1543 sorted(e.name() for e in compengines if e.available()), |
|
1544 name='compengine', |
|
1545 fmt='%s', |
|
1546 sep=', ', |
|
1547 ), |
|
1548 ) |
1317 wirecompengines = compression.compengines.supportedwireengines( |
1549 wirecompengines = compression.compengines.supportedwireengines( |
1318 compression.SERVERROLE) |
1550 compression.SERVERROLE |
1319 fm.write('compenginesserver', _('checking available compression engines ' |
1551 ) |
1320 'for wire protocol (%s)\n'), |
1552 fm.write( |
1321 fm.formatlist([e.name() for e in wirecompengines |
1553 'compenginesserver', |
1322 if e.wireprotosupport()], |
1554 _('checking available compression engines ' 'for wire protocol (%s)\n'), |
1323 name='compengine', fmt='%s', sep=', ')) |
1555 fm.formatlist( |
|
1556 [e.name() for e in wirecompengines if e.wireprotosupport()], |
|
1557 name='compengine', |
|
1558 fmt='%s', |
|
1559 sep=', ', |
|
1560 ), |
|
1561 ) |
1324 re2 = 'missing' |
1562 re2 = 'missing' |
1325 if util._re2: |
1563 if util._re2: |
1326 re2 = 'available' |
1564 re2 = 'available' |
1327 fm.plain(_('checking "re2" regexp engine (%s)\n') % re2) |
1565 fm.plain(_('checking "re2" regexp engine (%s)\n') % re2) |
1328 fm.data(re2=bool(util._re2)) |
1566 fm.data(re2=bool(util._re2)) |
1342 err = stringutil.forcebytestr(inst) |
1580 err = stringutil.forcebytestr(inst) |
1343 p = None |
1581 p = None |
1344 fm.condwrite(err, 'defaulttemplateerror', " %s\n", err) |
1582 fm.condwrite(err, 'defaulttemplateerror', " %s\n", err) |
1345 else: |
1583 else: |
1346 p = None |
1584 p = None |
1347 fm.condwrite(p, 'defaulttemplate', |
1585 fm.condwrite( |
1348 _("checking default template (%s)\n"), m) |
1586 p, 'defaulttemplate', _("checking default template (%s)\n"), m |
1349 fm.condwrite(not m, 'defaulttemplatenotfound', |
1587 ) |
1350 _(" template '%s' not found\n"), "default") |
1588 fm.condwrite( |
|
1589 not m, |
|
1590 'defaulttemplatenotfound', |
|
1591 _(" template '%s' not found\n"), |
|
1592 "default", |
|
1593 ) |
1351 if not p: |
1594 if not p: |
1352 problems += 1 |
1595 problems += 1 |
1353 fm.condwrite(not p, '', |
1596 fm.condwrite( |
1354 _(" (templates seem to have been installed incorrectly)\n")) |
1597 not p, '', _(" (templates seem to have been installed incorrectly)\n") |
|
1598 ) |
1355 |
1599 |
1356 # editor |
1600 # editor |
1357 editor = ui.geteditor() |
1601 editor = ui.geteditor() |
1358 editor = util.expandpath(editor) |
1602 editor = util.expandpath(editor) |
1359 editorbin = procutil.shellsplit(editor)[0] |
1603 editorbin = procutil.shellsplit(editor)[0] |
1360 fm.write('editor', _("checking commit editor... (%s)\n"), editorbin) |
1604 fm.write('editor', _("checking commit editor... (%s)\n"), editorbin) |
1361 cmdpath = procutil.findexe(editorbin) |
1605 cmdpath = procutil.findexe(editorbin) |
1362 fm.condwrite(not cmdpath and editor == 'vi', 'vinotfound', |
1606 fm.condwrite( |
1363 _(" No commit editor set and can't find %s in PATH\n" |
1607 not cmdpath and editor == 'vi', |
1364 " (specify a commit editor in your configuration" |
1608 'vinotfound', |
1365 " file)\n"), not cmdpath and editor == 'vi' and editorbin) |
1609 _( |
1366 fm.condwrite(not cmdpath and editor != 'vi', 'editornotfound', |
1610 " No commit editor set and can't find %s in PATH\n" |
1367 _(" Can't find editor '%s' in PATH\n" |
1611 " (specify a commit editor in your configuration" |
1368 " (specify a commit editor in your configuration" |
1612 " file)\n" |
1369 " file)\n"), not cmdpath and editorbin) |
1613 ), |
|
1614 not cmdpath and editor == 'vi' and editorbin, |
|
1615 ) |
|
1616 fm.condwrite( |
|
1617 not cmdpath and editor != 'vi', |
|
1618 'editornotfound', |
|
1619 _( |
|
1620 " Can't find editor '%s' in PATH\n" |
|
1621 " (specify a commit editor in your configuration" |
|
1622 " file)\n" |
|
1623 ), |
|
1624 not cmdpath and editorbin, |
|
1625 ) |
1370 if not cmdpath and editor != 'vi': |
1626 if not cmdpath and editor != 'vi': |
1371 problems += 1 |
1627 problems += 1 |
1372 |
1628 |
1373 # check username |
1629 # check username |
1374 username = None |
1630 username = None |
1377 username = ui.username() |
1633 username = ui.username() |
1378 except error.Abort as e: |
1634 except error.Abort as e: |
1379 err = stringutil.forcebytestr(e) |
1635 err = stringutil.forcebytestr(e) |
1380 problems += 1 |
1636 problems += 1 |
1381 |
1637 |
1382 fm.condwrite(username, 'username', _("checking username (%s)\n"), username) |
1638 fm.condwrite(username, 'username', _("checking username (%s)\n"), username) |
1383 fm.condwrite(err, 'usernameerror', _("checking username...\n %s\n" |
1639 fm.condwrite( |
1384 " (specify a username in your configuration file)\n"), err) |
1640 err, |
|
1641 'usernameerror', |
|
1642 _( |
|
1643 "checking username...\n %s\n" |
|
1644 " (specify a username in your configuration file)\n" |
|
1645 ), |
|
1646 err, |
|
1647 ) |
1385 |
1648 |
1386 for name, mod in extensions.extensions(): |
1649 for name, mod in extensions.extensions(): |
1387 handler = getattr(mod, 'debuginstall', None) |
1650 handler = getattr(mod, 'debuginstall', None) |
1388 if handler is not None: |
1651 if handler is not None: |
1389 problems += handler(ui, fm) |
1652 problems += handler(ui, fm) |
1390 |
1653 |
1391 fm.condwrite(not problems, '', |
1654 fm.condwrite(not problems, '', _("no problems detected\n")) |
1392 _("no problems detected\n")) |
|
1393 if not problems: |
1655 if not problems: |
1394 fm.data(problems=problems) |
1656 fm.data(problems=problems) |
1395 fm.condwrite(problems, 'problems', |
1657 fm.condwrite( |
1396 _("%d problems detected," |
1658 problems, |
1397 " please check your install!\n"), problems) |
1659 'problems', |
|
1660 _("%d problems detected," " please check your install!\n"), |
|
1661 problems, |
|
1662 ) |
1398 fm.end() |
1663 fm.end() |
1399 |
1664 |
1400 return problems |
1665 return problems |
|
1666 |
1401 |
1667 |
1402 @command('debugknown', [], _('REPO ID...'), norepo=True) |
1668 @command('debugknown', [], _('REPO ID...'), norepo=True) |
1403 def debugknown(ui, repopath, *ids, **opts): |
1669 def debugknown(ui, repopath, *ids, **opts): |
1404 """test whether node ids are known to a repo |
1670 """test whether node ids are known to a repo |
1405 |
1671 |
1411 if not repo.capable('known'): |
1677 if not repo.capable('known'): |
1412 raise error.Abort("known() not supported by target repository") |
1678 raise error.Abort("known() not supported by target repository") |
1413 flags = repo.known([bin(s) for s in ids]) |
1679 flags = repo.known([bin(s) for s in ids]) |
1414 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags]))) |
1680 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags]))) |
1415 |
1681 |
|
1682 |
1416 @command('debuglabelcomplete', [], _('LABEL...')) |
1683 @command('debuglabelcomplete', [], _('LABEL...')) |
1417 def debuglabelcomplete(ui, repo, *args): |
1684 def debuglabelcomplete(ui, repo, *args): |
1418 '''backwards compatibility with old bash completion scripts (DEPRECATED)''' |
1685 '''backwards compatibility with old bash completion scripts (DEPRECATED)''' |
1419 debugnamecomplete(ui, repo, *args) |
1686 debugnamecomplete(ui, repo, *args) |
1420 |
1687 |
1421 @command('debuglocks', |
1688 |
1422 [('L', 'force-lock', None, _('free the store lock (DANGEROUS)')), |
1689 @command( |
1423 ('W', 'force-wlock', None, |
1690 'debuglocks', |
1424 _('free the working state lock (DANGEROUS)')), |
1691 [ |
1425 ('s', 'set-lock', None, _('set the store lock until stopped')), |
1692 ('L', 'force-lock', None, _('free the store lock (DANGEROUS)')), |
1426 ('S', 'set-wlock', None, |
1693 ( |
1427 _('set the working state lock until stopped'))], |
1694 'W', |
1428 _('[OPTION]...')) |
1695 'force-wlock', |
|
1696 None, |
|
1697 _('free the working state lock (DANGEROUS)'), |
|
1698 ), |
|
1699 ('s', 'set-lock', None, _('set the store lock until stopped')), |
|
1700 ('S', 'set-wlock', None, _('set the working state lock until stopped')), |
|
1701 ], |
|
1702 _('[OPTION]...'), |
|
1703 ) |
1429 def debuglocks(ui, repo, **opts): |
1704 def debuglocks(ui, repo, **opts): |
1430 """show or modify state of locks |
1705 """show or modify state of locks |
1431 |
1706 |
1432 By default, this command will show which locks are held. This |
1707 By default, this command will show which locks are held. This |
1433 includes the user and process holding the lock, the amount of time |
1708 includes the user and process holding the lock, the amount of time |
1497 if ":" in locker: |
1772 if ":" in locker: |
1498 host, pid = locker.split(':') |
1773 host, pid = locker.split(':') |
1499 if host == socket.gethostname(): |
1774 if host == socket.gethostname(): |
1500 locker = 'user %s, process %s' % (user or b'None', pid) |
1775 locker = 'user %s, process %s' % (user or b'None', pid) |
1501 else: |
1776 else: |
1502 locker = ('user %s, process %s, host %s' |
1777 locker = 'user %s, process %s, host %s' % ( |
1503 % (user or b'None', pid, host)) |
1778 user or b'None', |
1504 ui.write(("%-6s %s (%ds)\n") % (name + ":", locker, age)) |
1779 pid, |
|
1780 host, |
|
1781 ) |
|
1782 ui.write("%-6s %s (%ds)\n" % (name + ":", locker, age)) |
1505 return 1 |
1783 return 1 |
1506 except OSError as e: |
1784 except OSError as e: |
1507 if e.errno != errno.ENOENT: |
1785 if e.errno != errno.ENOENT: |
1508 raise |
1786 raise |
1509 |
1787 |
1510 ui.write(("%-6s free\n") % (name + ":")) |
1788 ui.write("%-6s free\n" % (name + ":")) |
1511 return 0 |
1789 return 0 |
1512 |
1790 |
1513 held += report(repo.svfs, "lock", repo.lock) |
1791 held += report(repo.svfs, "lock", repo.lock) |
1514 held += report(repo.vfs, "wlock", repo.wlock) |
1792 held += report(repo.vfs, "wlock", repo.wlock) |
1515 |
1793 |
1516 return held |
1794 return held |
1517 |
1795 |
1518 @command('debugmanifestfulltextcache', [ |
1796 |
|
1797 @command( |
|
1798 'debugmanifestfulltextcache', |
|
1799 [ |
1519 ('', 'clear', False, _('clear the cache')), |
1800 ('', 'clear', False, _('clear the cache')), |
1520 ('a', 'add', [], _('add the given manifest nodes to the cache'), |
1801 ( |
1521 _('NODE')) |
1802 'a', |
1522 ], '') |
1803 'add', |
|
1804 [], |
|
1805 _('add the given manifest nodes to the cache'), |
|
1806 _('NODE'), |
|
1807 ), |
|
1808 ], |
|
1809 '', |
|
1810 ) |
1523 def debugmanifestfulltextcache(ui, repo, add=(), **opts): |
1811 def debugmanifestfulltextcache(ui, repo, add=(), **opts): |
1524 """show, clear or amend the contents of the manifest fulltext cache""" |
1812 """show, clear or amend the contents of the manifest fulltext cache""" |
1525 |
1813 |
1526 def getcache(): |
1814 def getcache(): |
1527 r = repo.manifestlog.getstorage(b'') |
1815 r = repo.manifestlog.getstorage(b'') |
1528 try: |
1816 try: |
1529 return r._fulltextcache |
1817 return r._fulltextcache |
1530 except AttributeError: |
1818 except AttributeError: |
1531 msg = _("Current revlog implementation doesn't appear to have a " |
1819 msg = _( |
1532 "manifest fulltext cache\n") |
1820 "Current revlog implementation doesn't appear to have a " |
|
1821 "manifest fulltext cache\n" |
|
1822 ) |
1533 raise error.Abort(msg) |
1823 raise error.Abort(msg) |
1534 |
1824 |
1535 if opts.get(r'clear'): |
1825 if opts.get(r'clear'): |
1536 with repo.wlock(): |
1826 with repo.wlock(): |
1537 cache = getcache() |
1827 cache = getcache() |
1553 cache = getcache() |
1843 cache = getcache() |
1554 if not len(cache): |
1844 if not len(cache): |
1555 ui.write(_('cache empty\n')) |
1845 ui.write(_('cache empty\n')) |
1556 else: |
1846 else: |
1557 ui.write( |
1847 ui.write( |
1558 _('cache contains %d manifest entries, in order of most to ' |
1848 _( |
1559 'least recent:\n') % (len(cache),)) |
1849 'cache contains %d manifest entries, in order of most to ' |
|
1850 'least recent:\n' |
|
1851 ) |
|
1852 % (len(cache),) |
|
1853 ) |
1560 totalsize = 0 |
1854 totalsize = 0 |
1561 for nodeid in cache: |
1855 for nodeid in cache: |
1562 # Use cache.get to not update the LRU order |
1856 # Use cache.get to not update the LRU order |
1563 data = cache.peek(nodeid) |
1857 data = cache.peek(nodeid) |
1564 size = len(data) |
1858 size = len(data) |
1565 totalsize += size + 24 # 20 bytes nodeid, 4 bytes size |
1859 totalsize += size + 24 # 20 bytes nodeid, 4 bytes size |
1566 ui.write(_('id: %s, size %s\n') % ( |
1860 ui.write( |
1567 hex(nodeid), util.bytecount(size))) |
1861 _('id: %s, size %s\n') % (hex(nodeid), util.bytecount(size)) |
|
1862 ) |
1568 ondisk = cache._opener.stat('manifestfulltextcache').st_size |
1863 ondisk = cache._opener.stat('manifestfulltextcache').st_size |
1569 ui.write( |
1864 ui.write( |
1570 _('total cache data size %s, on-disk %s\n') % ( |
1865 _('total cache data size %s, on-disk %s\n') |
1571 util.bytecount(totalsize), util.bytecount(ondisk)) |
1866 % (util.bytecount(totalsize), util.bytecount(ondisk)) |
1572 ) |
1867 ) |
|
1868 |
1573 |
1869 |
1574 @command('debugmergestate', [], '') |
1870 @command('debugmergestate', [], '') |
1575 def debugmergestate(ui, repo, *args): |
1871 def debugmergestate(ui, repo, *args): |
1576 """print merge state |
1872 """print merge state |
1577 |
1873 |
1578 Use --verbose to print out information about whether v1 or v2 merge state |
1874 Use --verbose to print out information about whether v1 or v2 merge state |
1579 was chosen.""" |
1875 was chosen.""" |
|
1876 |
1580 def _hashornull(h): |
1877 def _hashornull(h): |
1581 if h == nullhex: |
1878 if h == nullhex: |
1582 return 'null' |
1879 return 'null' |
1583 else: |
1880 else: |
1584 return h |
1881 return h |
1585 |
1882 |
1586 def printrecords(version): |
1883 def printrecords(version): |
1587 ui.write(('* version %d records\n') % version) |
1884 ui.write('* version %d records\n' % version) |
1588 if version == 1: |
1885 if version == 1: |
1589 records = v1records |
1886 records = v1records |
1590 else: |
1887 else: |
1591 records = v2records |
1888 records = v2records |
1592 |
1889 |
1593 for rtype, record in records: |
1890 for rtype, record in records: |
1594 # pretty print some record types |
1891 # pretty print some record types |
1595 if rtype == 'L': |
1892 if rtype == 'L': |
1596 ui.write(('local: %s\n') % record) |
1893 ui.write('local: %s\n' % record) |
1597 elif rtype == 'O': |
1894 elif rtype == 'O': |
1598 ui.write(('other: %s\n') % record) |
1895 ui.write('other: %s\n' % record) |
1599 elif rtype == 'm': |
1896 elif rtype == 'm': |
1600 driver, mdstate = record.split('\0', 1) |
1897 driver, mdstate = record.split('\0', 1) |
1601 ui.write(('merge driver: %s (state "%s")\n') |
1898 ui.write('merge driver: %s (state "%s")\n' % (driver, mdstate)) |
1602 % (driver, mdstate)) |
|
1603 elif rtype in 'FDC': |
1899 elif rtype in 'FDC': |
1604 r = record.split('\0') |
1900 r = record.split('\0') |
1605 f, state, hash, lfile, afile, anode, ofile = r[0:7] |
1901 f, state, hash, lfile, afile, anode, ofile = r[0:7] |
1606 if version == 1: |
1902 if version == 1: |
1607 onode = 'not stored in v1 format' |
1903 onode = 'not stored in v1 format' |
1608 flags = r[7] |
1904 flags = r[7] |
1609 else: |
1905 else: |
1610 onode, flags = r[7:9] |
1906 onode, flags = r[7:9] |
1611 ui.write(('file: %s (record type "%s", state "%s", hash %s)\n') |
1907 ui.write( |
1612 % (f, rtype, state, _hashornull(hash))) |
1908 'file: %s (record type "%s", state "%s", hash %s)\n' |
1613 ui.write((' local path: %s (flags "%s")\n') % (lfile, flags)) |
1909 % (f, rtype, state, _hashornull(hash)) |
1614 ui.write((' ancestor path: %s (node %s)\n') |
1910 ) |
1615 % (afile, _hashornull(anode))) |
1911 ui.write(' local path: %s (flags "%s")\n' % (lfile, flags)) |
1616 ui.write((' other path: %s (node %s)\n') |
1912 ui.write( |
1617 % (ofile, _hashornull(onode))) |
1913 ' ancestor path: %s (node %s)\n' |
|
1914 % (afile, _hashornull(anode)) |
|
1915 ) |
|
1916 ui.write( |
|
1917 ' other path: %s (node %s)\n' % (ofile, _hashornull(onode)) |
|
1918 ) |
1618 elif rtype == 'f': |
1919 elif rtype == 'f': |
1619 filename, rawextras = record.split('\0', 1) |
1920 filename, rawextras = record.split('\0', 1) |
1620 extras = rawextras.split('\0') |
1921 extras = rawextras.split('\0') |
1621 i = 0 |
1922 i = 0 |
1622 extrastrings = [] |
1923 extrastrings = [] |
1623 while i < len(extras): |
1924 while i < len(extras): |
1624 extrastrings.append('%s = %s' % (extras[i], extras[i + 1])) |
1925 extrastrings.append('%s = %s' % (extras[i], extras[i + 1])) |
1625 i += 2 |
1926 i += 2 |
1626 |
1927 |
1627 ui.write(('file extras: %s (%s)\n') |
1928 ui.write( |
1628 % (filename, ', '.join(extrastrings))) |
1929 'file extras: %s (%s)\n' |
|
1930 % (filename, ', '.join(extrastrings)) |
|
1931 ) |
1629 elif rtype == 'l': |
1932 elif rtype == 'l': |
1630 labels = record.split('\0', 2) |
1933 labels = record.split('\0', 2) |
1631 labels = [l for l in labels if len(l) > 0] |
1934 labels = [l for l in labels if len(l) > 0] |
1632 ui.write(('labels:\n')) |
1935 ui.write('labels:\n') |
1633 ui.write((' local: %s\n' % labels[0])) |
1936 ui.write((' local: %s\n' % labels[0])) |
1634 ui.write((' other: %s\n' % labels[1])) |
1937 ui.write((' other: %s\n' % labels[1])) |
1635 if len(labels) > 2: |
1938 if len(labels) > 2: |
1636 ui.write((' base: %s\n' % labels[2])) |
1939 ui.write((' base: %s\n' % labels[2])) |
1637 else: |
1940 else: |
1638 ui.write(('unrecognized entry: %s\t%s\n') |
1941 ui.write( |
1639 % (rtype, record.replace('\0', '\t'))) |
1942 'unrecognized entry: %s\t%s\n' |
|
1943 % (rtype, record.replace('\0', '\t')) |
|
1944 ) |
1640 |
1945 |
1641 # Avoid mergestate.read() since it may raise an exception for unsupported |
1946 # Avoid mergestate.read() since it may raise an exception for unsupported |
1642 # merge state records. We shouldn't be doing this, but this is OK since this |
1947 # merge state records. We shouldn't be doing this, but this is OK since this |
1643 # command is pretty low-level. |
1948 # command is pretty low-level. |
1644 ms = mergemod.mergestate(repo) |
1949 ms = mergemod.mergestate(repo) |
1645 |
1950 |
1646 # sort so that reasonable information is on top |
1951 # sort so that reasonable information is on top |
1647 v1records = ms._readrecordsv1() |
1952 v1records = ms._readrecordsv1() |
1648 v2records = ms._readrecordsv2() |
1953 v2records = ms._readrecordsv2() |
1649 order = 'LOml' |
1954 order = 'LOml' |
|
1955 |
1650 def key(r): |
1956 def key(r): |
1651 idx = order.find(r[0]) |
1957 idx = order.find(r[0]) |
1652 if idx == -1: |
1958 if idx == -1: |
1653 return (1, r[1]) |
1959 return (1, r[1]) |
1654 else: |
1960 else: |
1655 return (0, idx) |
1961 return (0, idx) |
|
1962 |
1656 v1records.sort(key=key) |
1963 v1records.sort(key=key) |
1657 v2records.sort(key=key) |
1964 v2records.sort(key=key) |
1658 |
1965 |
1659 if not v1records and not v2records: |
1966 if not v1records and not v2records: |
1660 ui.write(('no merge state found\n')) |
1967 ui.write('no merge state found\n') |
1661 elif not v2records: |
1968 elif not v2records: |
1662 ui.note(('no version 2 merge state\n')) |
1969 ui.note('no version 2 merge state\n') |
1663 printrecords(1) |
1970 printrecords(1) |
1664 elif ms._v1v2match(v1records, v2records): |
1971 elif ms._v1v2match(v1records, v2records): |
1665 ui.note(('v1 and v2 states match: using v2\n')) |
1972 ui.note('v1 and v2 states match: using v2\n') |
1666 printrecords(2) |
1973 printrecords(2) |
1667 else: |
1974 else: |
1668 ui.note(('v1 and v2 states mismatch: using v1\n')) |
1975 ui.note('v1 and v2 states mismatch: using v1\n') |
1669 printrecords(1) |
1976 printrecords(1) |
1670 if ui.verbose: |
1977 if ui.verbose: |
1671 printrecords(2) |
1978 printrecords(2) |
|
1979 |
1672 |
1980 |
1673 @command('debugnamecomplete', [], _('NAME...')) |
1981 @command('debugnamecomplete', [], _('NAME...')) |
1674 def debugnamecomplete(ui, repo, *args): |
1982 def debugnamecomplete(ui, repo, *args): |
1675 '''complete "names" - tags, open branch names, bookmark names''' |
1983 '''complete "names" - tags, open branch names, bookmark names''' |
1676 |
1984 |
1678 # since we previously only listed open branches, we will handle that |
1986 # since we previously only listed open branches, we will handle that |
1679 # specially (after this for loop) |
1987 # specially (after this for loop) |
1680 for name, ns in repo.names.iteritems(): |
1988 for name, ns in repo.names.iteritems(): |
1681 if name != 'branches': |
1989 if name != 'branches': |
1682 names.update(ns.listnames(repo)) |
1990 names.update(ns.listnames(repo)) |
1683 names.update(tag for (tag, heads, tip, closed) |
1991 names.update( |
1684 in repo.branchmap().iterbranches() if not closed) |
1992 tag |
|
1993 for (tag, heads, tip, closed) in repo.branchmap().iterbranches() |
|
1994 if not closed |
|
1995 ) |
1685 completions = set() |
1996 completions = set() |
1686 if not args: |
1997 if not args: |
1687 args = [''] |
1998 args = [''] |
1688 for a in args: |
1999 for a in args: |
1689 completions.update(n for n in names if n.startswith(a)) |
2000 completions.update(n for n in names if n.startswith(a)) |
1690 ui.write('\n'.join(sorted(completions))) |
2001 ui.write('\n'.join(sorted(completions))) |
1691 ui.write('\n') |
2002 ui.write('\n') |
1692 |
2003 |
1693 @command('debugobsolete', |
2004 |
1694 [('', 'flags', 0, _('markers flag')), |
2005 @command( |
1695 ('', 'record-parents', False, |
2006 'debugobsolete', |
1696 _('record parent information for the precursor')), |
2007 [ |
1697 ('r', 'rev', [], _('display markers relevant to REV')), |
2008 ('', 'flags', 0, _('markers flag')), |
1698 ('', 'exclusive', False, _('restrict display to markers only ' |
2009 ( |
1699 'relevant to REV')), |
2010 '', |
1700 ('', 'index', False, _('display index of the marker')), |
2011 'record-parents', |
1701 ('', 'delete', [], _('delete markers specified by indices')), |
2012 False, |
1702 ] + cmdutil.commitopts2 + cmdutil.formatteropts, |
2013 _('record parent information for the precursor'), |
1703 _('[OBSOLETED [REPLACEMENT ...]]')) |
2014 ), |
|
2015 ('r', 'rev', [], _('display markers relevant to REV')), |
|
2016 ( |
|
2017 '', |
|
2018 'exclusive', |
|
2019 False, |
|
2020 _('restrict display to markers only ' 'relevant to REV'), |
|
2021 ), |
|
2022 ('', 'index', False, _('display index of the marker')), |
|
2023 ('', 'delete', [], _('delete markers specified by indices')), |
|
2024 ] |
|
2025 + cmdutil.commitopts2 |
|
2026 + cmdutil.formatteropts, |
|
2027 _('[OBSOLETED [REPLACEMENT ...]]'), |
|
2028 ) |
1704 def debugobsolete(ui, repo, precursor=None, *successors, **opts): |
2029 def debugobsolete(ui, repo, precursor=None, *successors, **opts): |
1705 """create arbitrary obsolete marker |
2030 """create arbitrary obsolete marker |
1706 |
2031 |
1707 With no arguments, displays the list of obsolescence markers.""" |
2032 With no arguments, displays the list of obsolescence markers.""" |
1708 |
2033 |
1757 date = None |
2087 date = None |
1758 prec = parsenodeid(precursor) |
2088 prec = parsenodeid(precursor) |
1759 parents = None |
2089 parents = None |
1760 if opts['record_parents']: |
2090 if opts['record_parents']: |
1761 if prec not in repo.unfiltered(): |
2091 if prec not in repo.unfiltered(): |
1762 raise error.Abort('cannot used --record-parents on ' |
2092 raise error.Abort( |
1763 'unknown changesets') |
2093 'cannot used --record-parents on ' |
|
2094 'unknown changesets' |
|
2095 ) |
1764 parents = repo.unfiltered()[prec].parents() |
2096 parents = repo.unfiltered()[prec].parents() |
1765 parents = tuple(p.node() for p in parents) |
2097 parents = tuple(p.node() for p in parents) |
1766 repo.obsstore.create(tr, prec, succs, opts['flags'], |
2098 repo.obsstore.create( |
1767 parents=parents, date=date, |
2099 tr, |
1768 metadata=metadata, ui=ui) |
2100 prec, |
|
2101 succs, |
|
2102 opts['flags'], |
|
2103 parents=parents, |
|
2104 date=date, |
|
2105 metadata=metadata, |
|
2106 ui=ui, |
|
2107 ) |
1769 tr.close() |
2108 tr.close() |
1770 except ValueError as exc: |
2109 except ValueError as exc: |
1771 raise error.Abort(_('bad obsmarker input: %s') % |
2110 raise error.Abort( |
1772 pycompat.bytestr(exc)) |
2111 _('bad obsmarker input: %s') % pycompat.bytestr(exc) |
|
2112 ) |
1773 finally: |
2113 finally: |
1774 tr.release() |
2114 tr.release() |
1775 finally: |
2115 finally: |
1776 l.release() |
2116 l.release() |
1777 else: |
2117 else: |
1778 if opts['rev']: |
2118 if opts['rev']: |
1779 revs = scmutil.revrange(repo, opts['rev']) |
2119 revs = scmutil.revrange(repo, opts['rev']) |
1780 nodes = [repo[r].node() for r in revs] |
2120 nodes = [repo[r].node() for r in revs] |
1781 markers = list(obsutil.getmarkers(repo, nodes=nodes, |
2121 markers = list( |
1782 exclusive=opts['exclusive'])) |
2122 obsutil.getmarkers( |
|
2123 repo, nodes=nodes, exclusive=opts['exclusive'] |
|
2124 ) |
|
2125 ) |
1783 markers.sort(key=lambda x: x._data) |
2126 markers.sort(key=lambda x: x._data) |
1784 else: |
2127 else: |
1785 markers = obsutil.getmarkers(repo) |
2128 markers = obsutil.getmarkers(repo) |
1786 |
2129 |
1787 markerstoiter = markers |
2130 markerstoiter = markers |
1805 fm.startitem() |
2148 fm.startitem() |
1806 ind = i if opts.get('index') else None |
2149 ind = i if opts.get('index') else None |
1807 cmdutil.showmarker(fm, m, index=ind) |
2150 cmdutil.showmarker(fm, m, index=ind) |
1808 fm.end() |
2151 fm.end() |
1809 |
2152 |
1810 @command('debugp1copies', |
2153 |
1811 [('r', 'rev', '', _('revision to debug'), _('REV'))], |
2154 @command( |
1812 _('[-r REV]')) |
2155 'debugp1copies', |
|
2156 [('r', 'rev', '', _('revision to debug'), _('REV'))], |
|
2157 _('[-r REV]'), |
|
2158 ) |
1813 def debugp1copies(ui, repo, **opts): |
2159 def debugp1copies(ui, repo, **opts): |
1814 """dump copy information compared to p1""" |
2160 """dump copy information compared to p1""" |
1815 |
2161 |
1816 opts = pycompat.byteskwargs(opts) |
2162 opts = pycompat.byteskwargs(opts) |
1817 ctx = scmutil.revsingle(repo, opts.get('rev'), default=None) |
2163 ctx = scmutil.revsingle(repo, opts.get('rev'), default=None) |
1818 for dst, src in ctx.p1copies().items(): |
2164 for dst, src in ctx.p1copies().items(): |
1819 ui.write('%s -> %s\n' % (src, dst)) |
2165 ui.write('%s -> %s\n' % (src, dst)) |
1820 |
2166 |
1821 @command('debugp2copies', |
2167 |
1822 [('r', 'rev', '', _('revision to debug'), _('REV'))], |
2168 @command( |
1823 _('[-r REV]')) |
2169 'debugp2copies', |
|
2170 [('r', 'rev', '', _('revision to debug'), _('REV'))], |
|
2171 _('[-r REV]'), |
|
2172 ) |
1824 def debugp1copies(ui, repo, **opts): |
2173 def debugp1copies(ui, repo, **opts): |
1825 """dump copy information compared to p2""" |
2174 """dump copy information compared to p2""" |
1826 |
2175 |
1827 opts = pycompat.byteskwargs(opts) |
2176 opts = pycompat.byteskwargs(opts) |
1828 ctx = scmutil.revsingle(repo, opts.get('rev'), default=None) |
2177 ctx = scmutil.revsingle(repo, opts.get('rev'), default=None) |
1829 for dst, src in ctx.p2copies().items(): |
2178 for dst, src in ctx.p2copies().items(): |
1830 ui.write('%s -> %s\n' % (src, dst)) |
2179 ui.write('%s -> %s\n' % (src, dst)) |
1831 |
2180 |
1832 @command('debugpathcomplete', |
2181 |
1833 [('f', 'full', None, _('complete an entire path')), |
2182 @command( |
1834 ('n', 'normal', None, _('show only normal files')), |
2183 'debugpathcomplete', |
1835 ('a', 'added', None, _('show only added files')), |
2184 [ |
1836 ('r', 'removed', None, _('show only removed files'))], |
2185 ('f', 'full', None, _('complete an entire path')), |
1837 _('FILESPEC...')) |
2186 ('n', 'normal', None, _('show only normal files')), |
|
2187 ('a', 'added', None, _('show only added files')), |
|
2188 ('r', 'removed', None, _('show only removed files')), |
|
2189 ], |
|
2190 _('FILESPEC...'), |
|
2191 ) |
1838 def debugpathcomplete(ui, repo, *specs, **opts): |
2192 def debugpathcomplete(ui, repo, *specs, **opts): |
1839 '''complete part or all of a tracked path |
2193 '''complete part or all of a tracked path |
1840 |
2194 |
1841 This command supports shells that offer path name completion. It |
2195 This command supports shells that offer path name completion. It |
1842 currently completes only files already known to the dirstate. |
2196 currently completes only files already known to the dirstate. |
1892 dirs.update(d) |
2246 dirs.update(d) |
1893 files.update(dirs) |
2247 files.update(dirs) |
1894 ui.write('\n'.join(repo.pathto(p, cwd) for p in sorted(files))) |
2248 ui.write('\n'.join(repo.pathto(p, cwd) for p in sorted(files))) |
1895 ui.write('\n') |
2249 ui.write('\n') |
1896 |
2250 |
1897 @command('debugpathcopies', |
2251 |
1898 cmdutil.walkopts, |
2252 @command( |
1899 'hg debugpathcopies REV1 REV2 [FILE]', |
2253 'debugpathcopies', |
1900 inferrepo=True) |
2254 cmdutil.walkopts, |
|
2255 'hg debugpathcopies REV1 REV2 [FILE]', |
|
2256 inferrepo=True, |
|
2257 ) |
1901 def debugpathcopies(ui, repo, rev1, rev2, *pats, **opts): |
2258 def debugpathcopies(ui, repo, rev1, rev2, *pats, **opts): |
1902 """show copies between two revisions""" |
2259 """show copies between two revisions""" |
1903 ctx1 = scmutil.revsingle(repo, rev1) |
2260 ctx1 = scmutil.revsingle(repo, rev1) |
1904 ctx2 = scmutil.revsingle(repo, rev2) |
2261 ctx2 = scmutil.revsingle(repo, rev2) |
1905 m = scmutil.match(ctx1, pats, opts) |
2262 m = scmutil.match(ctx1, pats, opts) |
1906 for dst, src in sorted(copies.pathcopies(ctx1, ctx2, m).items()): |
2263 for dst, src in sorted(copies.pathcopies(ctx1, ctx2, m).items()): |
1907 ui.write('%s -> %s\n' % (src, dst)) |
2264 ui.write('%s -> %s\n' % (src, dst)) |
|
2265 |
1908 |
2266 |
1909 @command('debugpeer', [], _('PATH'), norepo=True) |
2267 @command('debugpeer', [], _('PATH'), norepo=True) |
1910 def debugpeer(ui, path): |
2268 def debugpeer(ui, path): |
1911 """establish a connection to a peer repository""" |
2269 """establish a connection to a peer repository""" |
1912 # Always enable peer request logging. Requires --debug to display |
2270 # Always enable peer request logging. Requires --debug to display |
1975 """ |
2339 """ |
1976 opts = pycompat.byteskwargs(opts) |
2340 opts = pycompat.byteskwargs(opts) |
1977 overrides = {} |
2341 overrides = {} |
1978 if opts['tool']: |
2342 if opts['tool']: |
1979 overrides[('ui', 'forcemerge')] = opts['tool'] |
2343 overrides[('ui', 'forcemerge')] = opts['tool'] |
1980 ui.note(('with --tool %r\n') % (pycompat.bytestr(opts['tool']))) |
2344 ui.note('with --tool %r\n' % (pycompat.bytestr(opts['tool']))) |
1981 |
2345 |
1982 with ui.configoverride(overrides, 'debugmergepatterns'): |
2346 with ui.configoverride(overrides, 'debugmergepatterns'): |
1983 hgmerge = encoding.environ.get("HGMERGE") |
2347 hgmerge = encoding.environ.get("HGMERGE") |
1984 if hgmerge is not None: |
2348 if hgmerge is not None: |
1985 ui.note(('with HGMERGE=%r\n') % (pycompat.bytestr(hgmerge))) |
2349 ui.note('with HGMERGE=%r\n' % (pycompat.bytestr(hgmerge))) |
1986 uimerge = ui.config("ui", "merge") |
2350 uimerge = ui.config("ui", "merge") |
1987 if uimerge: |
2351 if uimerge: |
1988 ui.note(('with ui.merge=%r\n') % (pycompat.bytestr(uimerge))) |
2352 ui.note('with ui.merge=%r\n' % (pycompat.bytestr(uimerge))) |
1989 |
2353 |
1990 ctx = scmutil.revsingle(repo, opts.get('rev')) |
2354 ctx = scmutil.revsingle(repo, opts.get('rev')) |
1991 m = scmutil.match(ctx, pats, opts) |
2355 m = scmutil.match(ctx, pats, opts) |
1992 changedelete = opts['changedelete'] |
2356 changedelete = opts['changedelete'] |
1993 for path in ctx.walk(m): |
2357 for path in ctx.walk(m): |
1994 fctx = ctx[path] |
2358 fctx = ctx[path] |
1995 try: |
2359 try: |
1996 if not ui.debugflag: |
2360 if not ui.debugflag: |
1997 ui.pushbuffer(error=True) |
2361 ui.pushbuffer(error=True) |
1998 tool, toolpath = filemerge._picktool(repo, ui, path, |
2362 tool, toolpath = filemerge._picktool( |
1999 fctx.isbinary(), |
2363 repo, |
2000 'l' in fctx.flags(), |
2364 ui, |
2001 changedelete) |
2365 path, |
|
2366 fctx.isbinary(), |
|
2367 'l' in fctx.flags(), |
|
2368 changedelete, |
|
2369 ) |
2002 finally: |
2370 finally: |
2003 if not ui.debugflag: |
2371 if not ui.debugflag: |
2004 ui.popbuffer() |
2372 ui.popbuffer() |
2005 ui.write(('%s = %s\n') % (path, tool)) |
2373 ui.write('%s = %s\n' % (path, tool)) |
|
2374 |
2006 |
2375 |
2007 @command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]'), norepo=True) |
2376 @command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]'), norepo=True) |
2008 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts): |
2377 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts): |
2009 '''access the pushkey key/value protocol |
2378 '''access the pushkey key/value protocol |
2010 |
2379 |
2047 elif pa | pb: |
2416 elif pa | pb: |
2048 rel = "|" |
2417 rel = "|" |
2049 ui.write(_("a: %s\n") % pa) |
2418 ui.write(_("a: %s\n") % pa) |
2050 ui.write(_("b: %s\n") % pb) |
2419 ui.write(_("b: %s\n") % pb) |
2051 ui.write(_("depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth)) |
2420 ui.write(_("depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth)) |
2052 ui.write(_("delta: %d hdist: %d distance: %d relation: %s\n") % |
2421 ui.write( |
2053 (abs(pa._depth - pb._depth), pvec._hamming(pa._vec, pb._vec), |
2422 _("delta: %d hdist: %d distance: %d relation: %s\n") |
2054 pa.distance(pb), rel)) |
2423 % ( |
2055 |
2424 abs(pa._depth - pb._depth), |
2056 @command('debugrebuilddirstate|debugrebuildstate', |
2425 pvec._hamming(pa._vec, pb._vec), |
2057 [('r', 'rev', '', _('revision to rebuild to'), _('REV')), |
2426 pa.distance(pb), |
2058 ('', 'minimal', None, _('only rebuild files that are inconsistent with ' |
2427 rel, |
2059 'the working copy parent')), |
2428 ) |
|
2429 ) |
|
2430 |
|
2431 |
|
2432 @command( |
|
2433 'debugrebuilddirstate|debugrebuildstate', |
|
2434 [ |
|
2435 ('r', 'rev', '', _('revision to rebuild to'), _('REV')), |
|
2436 ( |
|
2437 '', |
|
2438 'minimal', |
|
2439 None, |
|
2440 _( |
|
2441 'only rebuild files that are inconsistent with ' |
|
2442 'the working copy parent' |
|
2443 ), |
|
2444 ), |
2060 ], |
2445 ], |
2061 _('[-r REV]')) |
2446 _('[-r REV]'), |
|
2447 ) |
2062 def debugrebuilddirstate(ui, repo, rev, **opts): |
2448 def debugrebuilddirstate(ui, repo, rev, **opts): |
2063 """rebuild the dirstate as it would look like for the given revision |
2449 """rebuild the dirstate as it would look like for the given revision |
2064 |
2450 |
2065 If no revision is specified the first current parent will be used. |
2451 If no revision is specified the first current parent will be used. |
2066 |
2452 |
2089 dsnotadded = set(f for f in dsonly if dirstate[f] != 'a') |
2475 dsnotadded = set(f for f in dsonly if dirstate[f] != 'a') |
2090 changedfiles = manifestonly | dsnotadded |
2476 changedfiles = manifestonly | dsnotadded |
2091 |
2477 |
2092 dirstate.rebuild(ctx.node(), ctx.manifest(), changedfiles) |
2478 dirstate.rebuild(ctx.node(), ctx.manifest(), changedfiles) |
2093 |
2479 |
|
2480 |
2094 @command('debugrebuildfncache', [], '') |
2481 @command('debugrebuildfncache', [], '') |
2095 def debugrebuildfncache(ui, repo): |
2482 def debugrebuildfncache(ui, repo): |
2096 """rebuild the fncache file""" |
2483 """rebuild the fncache file""" |
2097 repair.rebuildfncache(ui, repo) |
2484 repair.rebuildfncache(ui, repo) |
2098 |
2485 |
2099 @command('debugrename', |
2486 |
|
2487 @command( |
|
2488 'debugrename', |
2100 [('r', 'rev', '', _('revision to debug'), _('REV'))], |
2489 [('r', 'rev', '', _('revision to debug'), _('REV'))], |
2101 _('[-r REV] [FILE]...')) |
2490 _('[-r REV] [FILE]...'), |
|
2491 ) |
2102 def debugrename(ui, repo, *pats, **opts): |
2492 def debugrename(ui, repo, *pats, **opts): |
2103 """dump rename information""" |
2493 """dump rename information""" |
2104 |
2494 |
2105 opts = pycompat.byteskwargs(opts) |
2495 opts = pycompat.byteskwargs(opts) |
2106 ctx = scmutil.revsingle(repo, opts.get('rev')) |
2496 ctx = scmutil.revsingle(repo, opts.get('rev')) |
2317 basedfmtstr = '%%%dd\n' |
2728 basedfmtstr = '%%%dd\n' |
2318 basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n' |
2729 basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n' |
2319 |
2730 |
2320 def dfmtstr(max): |
2731 def dfmtstr(max): |
2321 return basedfmtstr % len(str(max)) |
2732 return basedfmtstr % len(str(max)) |
|
2733 |
2322 def pcfmtstr(max, padding=0): |
2734 def pcfmtstr(max, padding=0): |
2323 return basepcfmtstr % (len(str(max)), ' ' * padding) |
2735 return basepcfmtstr % (len(str(max)), ' ' * padding) |
2324 |
2736 |
2325 def pcfmt(value, total): |
2737 def pcfmt(value, total): |
2326 if total: |
2738 if total: |
2327 return (value, 100 * float(value) / total) |
2739 return (value, 100 * float(value) / total) |
2328 else: |
2740 else: |
2329 return value, 100.0 |
2741 return value, 100.0 |
2330 |
2742 |
2331 ui.write(('format : %d\n') % format) |
2743 ui.write('format : %d\n' % format) |
2332 ui.write(('flags : %s\n') % ', '.join(flags)) |
2744 ui.write('flags : %s\n' % ', '.join(flags)) |
2333 |
2745 |
2334 ui.write('\n') |
2746 ui.write('\n') |
2335 fmt = pcfmtstr(totalsize) |
2747 fmt = pcfmtstr(totalsize) |
2336 fmt2 = dfmtstr(totalsize) |
2748 fmt2 = dfmtstr(totalsize) |
2337 ui.write(('revisions : ') + fmt2 % numrevs) |
2749 ui.write('revisions : ' + fmt2 % numrevs) |
2338 ui.write((' merges : ') + fmt % pcfmt(nummerges, numrevs)) |
2750 ui.write(' merges : ' + fmt % pcfmt(nummerges, numrevs)) |
2339 ui.write((' normal : ') + fmt % pcfmt(numrevs - nummerges, numrevs)) |
2751 ui.write(' normal : ' + fmt % pcfmt(numrevs - nummerges, numrevs)) |
2340 ui.write(('revisions : ') + fmt2 % numrevs) |
2752 ui.write('revisions : ' + fmt2 % numrevs) |
2341 ui.write((' empty : ') + fmt % pcfmt(numempty, numrevs)) |
2753 ui.write(' empty : ' + fmt % pcfmt(numempty, numrevs)) |
2342 ui.write((' text : ') |
2754 ui.write( |
2343 + fmt % pcfmt(numemptytext, numemptytext + numemptydelta)) |
2755 ' text : ' |
2344 ui.write((' delta : ') |
2756 + fmt % pcfmt(numemptytext, numemptytext + numemptydelta) |
2345 + fmt % pcfmt(numemptydelta, numemptytext + numemptydelta)) |
2757 ) |
2346 ui.write((' snapshot : ') + fmt % pcfmt(numfull + numsemi, numrevs)) |
2758 ui.write( |
|
2759 ' delta : ' |
|
2760 + fmt % pcfmt(numemptydelta, numemptytext + numemptydelta) |
|
2761 ) |
|
2762 ui.write(' snapshot : ' + fmt % pcfmt(numfull + numsemi, numrevs)) |
2347 for depth in sorted(numsnapdepth): |
2763 for depth in sorted(numsnapdepth): |
2348 ui.write((' lvl-%-3d : ' % depth) |
2764 ui.write( |
2349 + fmt % pcfmt(numsnapdepth[depth], numrevs)) |
2765 (' lvl-%-3d : ' % depth) |
2350 ui.write((' deltas : ') + fmt % pcfmt(numdeltas, numrevs)) |
2766 + fmt % pcfmt(numsnapdepth[depth], numrevs) |
2351 ui.write(('revision size : ') + fmt2 % totalsize) |
2767 ) |
2352 ui.write((' snapshot : ') |
2768 ui.write(' deltas : ' + fmt % pcfmt(numdeltas, numrevs)) |
2353 + fmt % pcfmt(fulltotal + semitotal, totalsize)) |
2769 ui.write('revision size : ' + fmt2 % totalsize) |
|
2770 ui.write(' snapshot : ' + fmt % pcfmt(fulltotal + semitotal, totalsize)) |
2354 for depth in sorted(numsnapdepth): |
2771 for depth in sorted(numsnapdepth): |
2355 ui.write((' lvl-%-3d : ' % depth) |
2772 ui.write( |
2356 + fmt % pcfmt(snaptotal[depth], totalsize)) |
2773 (' lvl-%-3d : ' % depth) |
2357 ui.write((' deltas : ') + fmt % pcfmt(deltatotal, totalsize)) |
2774 + fmt % pcfmt(snaptotal[depth], totalsize) |
|
2775 ) |
|
2776 ui.write(' deltas : ' + fmt % pcfmt(deltatotal, totalsize)) |
2358 |
2777 |
2359 def fmtchunktype(chunktype): |
2778 def fmtchunktype(chunktype): |
2360 if chunktype == 'empty': |
2779 if chunktype == 'empty': |
2361 return ' %s : ' % chunktype |
2780 return ' %s : ' % chunktype |
2362 elif chunktype in pycompat.bytestr(string.ascii_letters): |
2781 elif chunktype in pycompat.bytestr(string.ascii_letters): |
2363 return ' 0x%s (%s) : ' % (hex(chunktype), chunktype) |
2782 return ' 0x%s (%s) : ' % (hex(chunktype), chunktype) |
2364 else: |
2783 else: |
2365 return ' 0x%s : ' % hex(chunktype) |
2784 return ' 0x%s : ' % hex(chunktype) |
2366 |
2785 |
2367 ui.write('\n') |
2786 ui.write('\n') |
2368 ui.write(('chunks : ') + fmt2 % numrevs) |
2787 ui.write('chunks : ' + fmt2 % numrevs) |
2369 for chunktype in sorted(chunktypecounts): |
2788 for chunktype in sorted(chunktypecounts): |
2370 ui.write(fmtchunktype(chunktype)) |
2789 ui.write(fmtchunktype(chunktype)) |
2371 ui.write(fmt % pcfmt(chunktypecounts[chunktype], numrevs)) |
2790 ui.write(fmt % pcfmt(chunktypecounts[chunktype], numrevs)) |
2372 ui.write(('chunks size : ') + fmt2 % totalsize) |
2791 ui.write('chunks size : ' + fmt2 % totalsize) |
2373 for chunktype in sorted(chunktypecounts): |
2792 for chunktype in sorted(chunktypecounts): |
2374 ui.write(fmtchunktype(chunktype)) |
2793 ui.write(fmtchunktype(chunktype)) |
2375 ui.write(fmt % pcfmt(chunktypesizes[chunktype], totalsize)) |
2794 ui.write(fmt % pcfmt(chunktypesizes[chunktype], totalsize)) |
2376 |
2795 |
2377 ui.write('\n') |
2796 ui.write('\n') |
2378 fmt = dfmtstr(max(avgchainlen, maxchainlen, maxchainspan, compratio)) |
2797 fmt = dfmtstr(max(avgchainlen, maxchainlen, maxchainspan, compratio)) |
2379 ui.write(('avg chain length : ') + fmt % avgchainlen) |
2798 ui.write('avg chain length : ' + fmt % avgchainlen) |
2380 ui.write(('max chain length : ') + fmt % maxchainlen) |
2799 ui.write('max chain length : ' + fmt % maxchainlen) |
2381 ui.write(('max chain reach : ') + fmt % maxchainspan) |
2800 ui.write('max chain reach : ' + fmt % maxchainspan) |
2382 ui.write(('compression ratio : ') + fmt % compratio) |
2801 ui.write('compression ratio : ' + fmt % compratio) |
2383 |
2802 |
2384 if format > 0: |
2803 if format > 0: |
2385 ui.write('\n') |
2804 ui.write('\n') |
2386 ui.write(('uncompressed data size (min/max/avg) : %d / %d / %d\n') |
2805 ui.write( |
2387 % tuple(datasize)) |
2806 'uncompressed data size (min/max/avg) : %d / %d / %d\n' |
2388 ui.write(('full revision size (min/max/avg) : %d / %d / %d\n') |
2807 % tuple(datasize) |
2389 % tuple(fullsize)) |
2808 ) |
2390 ui.write(('inter-snapshot size (min/max/avg) : %d / %d / %d\n') |
2809 ui.write( |
2391 % tuple(semisize)) |
2810 'full revision size (min/max/avg) : %d / %d / %d\n' |
|
2811 % tuple(fullsize) |
|
2812 ) |
|
2813 ui.write( |
|
2814 'inter-snapshot size (min/max/avg) : %d / %d / %d\n' |
|
2815 % tuple(semisize) |
|
2816 ) |
2392 for depth in sorted(snapsizedepth): |
2817 for depth in sorted(snapsizedepth): |
2393 if depth == 0: |
2818 if depth == 0: |
2394 continue |
2819 continue |
2395 ui.write((' level-%-3d (min/max/avg) : %d / %d / %d\n') |
2820 ui.write( |
2396 % ((depth,) + tuple(snapsizedepth[depth]))) |
2821 ' level-%-3d (min/max/avg) : %d / %d / %d\n' |
2397 ui.write(('delta size (min/max/avg) : %d / %d / %d\n') |
2822 % ((depth,) + tuple(snapsizedepth[depth])) |
2398 % tuple(deltasize)) |
2823 ) |
|
2824 ui.write( |
|
2825 'delta size (min/max/avg) : %d / %d / %d\n' |
|
2826 % tuple(deltasize) |
|
2827 ) |
2399 |
2828 |
2400 if numdeltas > 0: |
2829 if numdeltas > 0: |
2401 ui.write('\n') |
2830 ui.write('\n') |
2402 fmt = pcfmtstr(numdeltas) |
2831 fmt = pcfmtstr(numdeltas) |
2403 fmt2 = pcfmtstr(numdeltas, 4) |
2832 fmt2 = pcfmtstr(numdeltas, 4) |
2404 ui.write(('deltas against prev : ') + fmt % pcfmt(numprev, numdeltas)) |
2833 ui.write('deltas against prev : ' + fmt % pcfmt(numprev, numdeltas)) |
2405 if numprev > 0: |
2834 if numprev > 0: |
2406 ui.write((' where prev = p1 : ') + fmt2 % pcfmt(nump1prev, |
2835 ui.write( |
2407 numprev)) |
2836 ' where prev = p1 : ' + fmt2 % pcfmt(nump1prev, numprev) |
2408 ui.write((' where prev = p2 : ') + fmt2 % pcfmt(nump2prev, |
2837 ) |
2409 numprev)) |
2838 ui.write( |
2410 ui.write((' other : ') + fmt2 % pcfmt(numoprev, |
2839 ' where prev = p2 : ' + fmt2 % pcfmt(nump2prev, numprev) |
2411 numprev)) |
2840 ) |
|
2841 ui.write( |
|
2842 ' other : ' + fmt2 % pcfmt(numoprev, numprev) |
|
2843 ) |
2412 if gdelta: |
2844 if gdelta: |
2413 ui.write(('deltas against p1 : ') |
2845 ui.write('deltas against p1 : ' + fmt % pcfmt(nump1, numdeltas)) |
2414 + fmt % pcfmt(nump1, numdeltas)) |
2846 ui.write('deltas against p2 : ' + fmt % pcfmt(nump2, numdeltas)) |
2415 ui.write(('deltas against p2 : ') |
2847 ui.write( |
2416 + fmt % pcfmt(nump2, numdeltas)) |
2848 'deltas against other : ' + fmt % pcfmt(numother, numdeltas) |
2417 ui.write(('deltas against other : ') + fmt % pcfmt(numother, |
2849 ) |
2418 numdeltas)) |
2850 |
2419 |
2851 |
2420 @command('debugrevlogindex', cmdutil.debugrevlogopts + |
2852 @command( |
2421 [('f', 'format', 0, _('revlog format'), _('FORMAT'))], |
2853 'debugrevlogindex', |
|
2854 cmdutil.debugrevlogopts |
|
2855 + [('f', 'format', 0, _('revlog format'), _('FORMAT'))], |
2422 _('[-f FORMAT] -c|-m|FILE'), |
2856 _('[-f FORMAT] -c|-m|FILE'), |
2423 optionalrepo=True) |
2857 optionalrepo=True, |
|
2858 ) |
2424 def debugrevlogindex(ui, repo, file_=None, **opts): |
2859 def debugrevlogindex(ui, repo, file_=None, **opts): |
2425 """dump the contents of a revlog index""" |
2860 """dump the contents of a revlog index""" |
2426 opts = pycompat.byteskwargs(opts) |
2861 opts = pycompat.byteskwargs(opts) |
2427 r = cmdutil.openrevlog(repo, 'debugrevlogindex', file_, opts) |
2862 r = cmdutil.openrevlog(repo, 'debugrevlogindex', file_, opts) |
2428 format = opts.get('format', 0) |
2863 format = opts.get('format', 0) |
2440 idlen = len(shortfn(r.node(i))) |
2875 idlen = len(shortfn(r.node(i))) |
2441 break |
2876 break |
2442 |
2877 |
2443 if format == 0: |
2878 if format == 0: |
2444 if ui.verbose: |
2879 if ui.verbose: |
2445 ui.write((" rev offset length linkrev" |
2880 ui.write( |
2446 " %s %s p2\n") % ("nodeid".ljust(idlen), |
2881 (" rev offset length linkrev" " %s %s p2\n") |
2447 "p1".ljust(idlen))) |
2882 % ("nodeid".ljust(idlen), "p1".ljust(idlen)) |
|
2883 ) |
2448 else: |
2884 else: |
2449 ui.write((" rev linkrev %s %s p2\n") % ( |
2885 ui.write( |
2450 "nodeid".ljust(idlen), "p1".ljust(idlen))) |
2886 " rev linkrev %s %s p2\n" |
|
2887 % ("nodeid".ljust(idlen), "p1".ljust(idlen)) |
|
2888 ) |
2451 elif format == 1: |
2889 elif format == 1: |
2452 if ui.verbose: |
2890 if ui.verbose: |
2453 ui.write((" rev flag offset length size link p1" |
2891 ui.write( |
2454 " p2 %s\n") % "nodeid".rjust(idlen)) |
2892 ( |
|
2893 " rev flag offset length size link p1" |
|
2894 " p2 %s\n" |
|
2895 ) |
|
2896 % "nodeid".rjust(idlen) |
|
2897 ) |
2455 else: |
2898 else: |
2456 ui.write((" rev flag size link p1 p2 %s\n") % |
2899 ui.write( |
2457 "nodeid".rjust(idlen)) |
2900 " rev flag size link p1 p2 %s\n" |
|
2901 % "nodeid".rjust(idlen) |
|
2902 ) |
2458 |
2903 |
2459 for i in r: |
2904 for i in r: |
2460 node = r.node(i) |
2905 node = r.node(i) |
2461 if format == 0: |
2906 if format == 0: |
2462 try: |
2907 try: |
2463 pp = r.parents(node) |
2908 pp = r.parents(node) |
2464 except Exception: |
2909 except Exception: |
2465 pp = [nullid, nullid] |
2910 pp = [nullid, nullid] |
2466 if ui.verbose: |
2911 if ui.verbose: |
2467 ui.write("% 6d % 9d % 7d % 7d %s %s %s\n" % ( |
2912 ui.write( |
2468 i, r.start(i), r.length(i), r.linkrev(i), |
2913 "% 6d % 9d % 7d % 7d %s %s %s\n" |
2469 shortfn(node), shortfn(pp[0]), shortfn(pp[1]))) |
2914 % ( |
|
2915 i, |
|
2916 r.start(i), |
|
2917 r.length(i), |
|
2918 r.linkrev(i), |
|
2919 shortfn(node), |
|
2920 shortfn(pp[0]), |
|
2921 shortfn(pp[1]), |
|
2922 ) |
|
2923 ) |
2470 else: |
2924 else: |
2471 ui.write("% 6d % 7d %s %s %s\n" % ( |
2925 ui.write( |
2472 i, r.linkrev(i), shortfn(node), shortfn(pp[0]), |
2926 "% 6d % 7d %s %s %s\n" |
2473 shortfn(pp[1]))) |
2927 % ( |
|
2928 i, |
|
2929 r.linkrev(i), |
|
2930 shortfn(node), |
|
2931 shortfn(pp[0]), |
|
2932 shortfn(pp[1]), |
|
2933 ) |
|
2934 ) |
2474 elif format == 1: |
2935 elif format == 1: |
2475 pr = r.parentrevs(i) |
2936 pr = r.parentrevs(i) |
2476 if ui.verbose: |
2937 if ui.verbose: |
2477 ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d %s\n" % ( |
2938 ui.write( |
2478 i, r.flags(i), r.start(i), r.length(i), r.rawsize(i), |
2939 "% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d %s\n" |
2479 r.linkrev(i), pr[0], pr[1], shortfn(node))) |
2940 % ( |
|
2941 i, |
|
2942 r.flags(i), |
|
2943 r.start(i), |
|
2944 r.length(i), |
|
2945 r.rawsize(i), |
|
2946 r.linkrev(i), |
|
2947 pr[0], |
|
2948 pr[1], |
|
2949 shortfn(node), |
|
2950 ) |
|
2951 ) |
2480 else: |
2952 else: |
2481 ui.write("% 6d %04x % 8d % 6d % 6d % 6d %s\n" % ( |
2953 ui.write( |
2482 i, r.flags(i), r.rawsize(i), r.linkrev(i), pr[0], pr[1], |
2954 "% 6d %04x % 8d % 6d % 6d % 6d %s\n" |
2483 shortfn(node))) |
2955 % ( |
2484 |
2956 i, |
2485 @command('debugrevspec', |
2957 r.flags(i), |
2486 [('', 'optimize', None, |
2958 r.rawsize(i), |
2487 _('print parsed tree after optimizing (DEPRECATED)')), |
2959 r.linkrev(i), |
2488 ('', 'show-revs', True, _('print list of result revisions (default)')), |
2960 pr[0], |
2489 ('s', 'show-set', None, _('print internal representation of result set')), |
2961 pr[1], |
2490 ('p', 'show-stage', [], |
2962 shortfn(node), |
2491 _('print parsed tree at the given stage'), _('NAME')), |
2963 ) |
2492 ('', 'no-optimized', False, _('evaluate tree without optimization')), |
2964 ) |
2493 ('', 'verify-optimized', False, _('verify optimized result')), |
2965 |
2494 ], |
2966 |
2495 ('REVSPEC')) |
2967 @command( |
|
2968 'debugrevspec', |
|
2969 [ |
|
2970 ( |
|
2971 '', |
|
2972 'optimize', |
|
2973 None, |
|
2974 _('print parsed tree after optimizing (DEPRECATED)'), |
|
2975 ), |
|
2976 ('', 'show-revs', True, _('print list of result revisions (default)')), |
|
2977 ( |
|
2978 's', |
|
2979 'show-set', |
|
2980 None, |
|
2981 _('print internal representation of result set'), |
|
2982 ), |
|
2983 ( |
|
2984 'p', |
|
2985 'show-stage', |
|
2986 [], |
|
2987 _('print parsed tree at the given stage'), |
|
2988 _('NAME'), |
|
2989 ), |
|
2990 ('', 'no-optimized', False, _('evaluate tree without optimization')), |
|
2991 ('', 'verify-optimized', False, _('verify optimized result')), |
|
2992 ], |
|
2993 'REVSPEC', |
|
2994 ) |
2496 def debugrevspec(ui, repo, expr, **opts): |
2995 def debugrevspec(ui, repo, expr, **opts): |
2497 """parse and apply a revision specification |
2996 """parse and apply a revision specification |
2498 |
2997 |
2499 Use -p/--show-stage option to print the parsed tree at the given stages. |
2998 Use -p/--show-stage option to print the parsed tree at the given stages. |
2500 Use -p all to print tree at every stage. |
2999 Use -p all to print tree at every stage. |
2545 tree = revsetlang.parse(expr, lookup=revset.lookupfn(repo)) |
3047 tree = revsetlang.parse(expr, lookup=revset.lookupfn(repo)) |
2546 for n, f in stages: |
3048 for n, f in stages: |
2547 treebystage[n] = tree = f(tree) |
3049 treebystage[n] = tree = f(tree) |
2548 if n in showalways or (n in showchanged and tree != printedtree): |
3050 if n in showalways or (n in showchanged and tree != printedtree): |
2549 if opts['show_stage'] or n != 'parsed': |
3051 if opts['show_stage'] or n != 'parsed': |
2550 ui.write(("* %s:\n") % n) |
3052 ui.write("* %s:\n" % n) |
2551 ui.write(revsetlang.prettyformat(tree), "\n") |
3053 ui.write(revsetlang.prettyformat(tree), "\n") |
2552 printedtree = tree |
3054 printedtree = tree |
2553 |
3055 |
2554 if opts['verify_optimized']: |
3056 if opts['verify_optimized']: |
2555 arevs = revset.makematcher(treebystage['analyzed'])(repo) |
3057 arevs = revset.makematcher(treebystage['analyzed'])(repo) |
2556 brevs = revset.makematcher(treebystage['optimized'])(repo) |
3058 brevs = revset.makematcher(treebystage['optimized'])(repo) |
2557 if opts['show_set'] or (opts['show_set'] is None and ui.verbose): |
3059 if opts['show_set'] or (opts['show_set'] is None and ui.verbose): |
2558 ui.write(("* analyzed set:\n"), stringutil.prettyrepr(arevs), "\n") |
3060 ui.write("* analyzed set:\n", stringutil.prettyrepr(arevs), "\n") |
2559 ui.write(("* optimized set:\n"), stringutil.prettyrepr(brevs), "\n") |
3061 ui.write("* optimized set:\n", stringutil.prettyrepr(brevs), "\n") |
2560 arevs = list(arevs) |
3062 arevs = list(arevs) |
2561 brevs = list(brevs) |
3063 brevs = list(brevs) |
2562 if arevs == brevs: |
3064 if arevs == brevs: |
2563 return 0 |
3065 return 0 |
2564 ui.write(('--- analyzed\n'), label='diff.file_a') |
3066 ui.write('--- analyzed\n', label='diff.file_a') |
2565 ui.write(('+++ optimized\n'), label='diff.file_b') |
3067 ui.write('+++ optimized\n', label='diff.file_b') |
2566 sm = difflib.SequenceMatcher(None, arevs, brevs) |
3068 sm = difflib.SequenceMatcher(None, arevs, brevs) |
2567 for tag, alo, ahi, blo, bhi in sm.get_opcodes(): |
3069 for tag, alo, ahi, blo, bhi in sm.get_opcodes(): |
2568 if tag in (r'delete', r'replace'): |
3070 if tag in (r'delete', r'replace'): |
2569 for c in arevs[alo:ahi]: |
3071 for c in arevs[alo:ahi]: |
2570 ui.write('-%d\n' % c, label='diff.deleted') |
3072 ui.write('-%d\n' % c, label='diff.deleted') |
2724 else: |
3248 else: |
2725 ui.status(_('full certificate chain is available\n')) |
3249 ui.status(_('full certificate chain is available\n')) |
2726 finally: |
3250 finally: |
2727 s.close() |
3251 s.close() |
2728 |
3252 |
2729 @command('debugsub', |
3253 |
2730 [('r', 'rev', '', |
3254 @command( |
2731 _('revision to check'), _('REV'))], |
3255 'debugsub', |
2732 _('[-r REV] [REV]')) |
3256 [('r', 'rev', '', _('revision to check'), _('REV'))], |
|
3257 _('[-r REV] [REV]'), |
|
3258 ) |
2733 def debugsub(ui, repo, rev=None): |
3259 def debugsub(ui, repo, rev=None): |
2734 ctx = scmutil.revsingle(repo, rev, None) |
3260 ctx = scmutil.revsingle(repo, rev, None) |
2735 for k, v in sorted(ctx.substate.items()): |
3261 for k, v in sorted(ctx.substate.items()): |
2736 ui.write(('path %s\n') % k) |
3262 ui.write('path %s\n' % k) |
2737 ui.write((' source %s\n') % v[0]) |
3263 ui.write(' source %s\n' % v[0]) |
2738 ui.write((' revision %s\n') % v[1]) |
3264 ui.write(' revision %s\n' % v[1]) |
2739 |
3265 |
2740 @command('debugsuccessorssets', |
3266 |
|
3267 @command( |
|
3268 'debugsuccessorssets', |
2741 [('', 'closest', False, _('return closest successors sets only'))], |
3269 [('', 'closest', False, _('return closest successors sets only'))], |
2742 _('[REV]')) |
3270 _('[REV]'), |
|
3271 ) |
2743 def debugsuccessorssets(ui, repo, *revs, **opts): |
3272 def debugsuccessorssets(ui, repo, *revs, **opts): |
2744 """show set of successors for revision |
3273 """show set of successors for revision |
2745 |
3274 |
2746 A successors set of changeset A is a consistent group of revisions that |
3275 A successors set of changeset A is a consistent group of revisions that |
2747 succeed A. It contains non-obsolete changesets only unless closests |
3276 succeed A. It contains non-obsolete changesets only unless closests |
2776 cache = {} |
3305 cache = {} |
2777 ctx2str = bytes |
3306 ctx2str = bytes |
2778 node2str = short |
3307 node2str = short |
2779 for rev in scmutil.revrange(repo, revs): |
3308 for rev in scmutil.revrange(repo, revs): |
2780 ctx = repo[rev] |
3309 ctx = repo[rev] |
2781 ui.write('%s\n'% ctx2str(ctx)) |
3310 ui.write('%s\n' % ctx2str(ctx)) |
2782 for succsset in obsutil.successorssets(repo, ctx.node(), |
3311 for succsset in obsutil.successorssets( |
2783 closest=opts[r'closest'], |
3312 repo, ctx.node(), closest=opts[r'closest'], cache=cache |
2784 cache=cache): |
3313 ): |
2785 if succsset: |
3314 if succsset: |
2786 ui.write(' ') |
3315 ui.write(' ') |
2787 ui.write(node2str(succsset[0])) |
3316 ui.write(node2str(succsset[0])) |
2788 for node in succsset[1:]: |
3317 for node in succsset[1:]: |
2789 ui.write(' ') |
3318 ui.write(' ') |
2790 ui.write(node2str(node)) |
3319 ui.write(node2str(node)) |
2791 ui.write('\n') |
3320 ui.write('\n') |
2792 |
3321 |
2793 @command('debugtemplate', |
3322 |
2794 [('r', 'rev', [], _('apply template on changesets'), _('REV')), |
3323 @command( |
2795 ('D', 'define', [], _('define template keyword'), _('KEY=VALUE'))], |
3324 'debugtemplate', |
|
3325 [ |
|
3326 ('r', 'rev', [], _('apply template on changesets'), _('REV')), |
|
3327 ('D', 'define', [], _('define template keyword'), _('KEY=VALUE')), |
|
3328 ], |
2796 _('[-r REV]... [-D KEY=VALUE]... TEMPLATE'), |
3329 _('[-r REV]... [-D KEY=VALUE]... TEMPLATE'), |
2797 optionalrepo=True) |
3330 optionalrepo=True, |
|
3331 ) |
2798 def debugtemplate(ui, repo, tmpl, **opts): |
3332 def debugtemplate(ui, repo, tmpl, **opts): |
2799 """parse and apply a template |
3333 """parse and apply a template |
2800 |
3334 |
2801 If -r/--rev is given, the template is processed as a log template and |
3335 If -r/--rev is given, the template is processed as a log template and |
2802 applied to the given changesets. Otherwise, it is processed as a generic |
3336 applied to the given changesets. Otherwise, it is processed as a generic |
2825 aliases = ui.configitems('templatealias') |
3360 aliases = ui.configitems('templatealias') |
2826 tree = templater.parse(tmpl) |
3361 tree = templater.parse(tmpl) |
2827 ui.note(templater.prettyformat(tree), '\n') |
3362 ui.note(templater.prettyformat(tree), '\n') |
2828 newtree = templater.expandaliases(tree, aliases) |
3363 newtree = templater.expandaliases(tree, aliases) |
2829 if newtree != tree: |
3364 if newtree != tree: |
2830 ui.note(("* expanded:\n"), templater.prettyformat(newtree), '\n') |
3365 ui.note("* expanded:\n", templater.prettyformat(newtree), '\n') |
2831 |
3366 |
2832 if revs is None: |
3367 if revs is None: |
2833 tres = formatter.templateresources(ui, repo) |
3368 tres = formatter.templateresources(ui, repo) |
2834 t = formatter.maketemplater(ui, tmpl, resources=tres) |
3369 t = formatter.maketemplater(ui, tmpl, resources=tres) |
2835 if ui.verbose: |
3370 if ui.verbose: |
2836 kwds, funcs = t.symbolsuseddefault() |
3371 kwds, funcs = t.symbolsuseddefault() |
2837 ui.write(("* keywords: %s\n") % ', '.join(sorted(kwds))) |
3372 ui.write("* keywords: %s\n" % ', '.join(sorted(kwds))) |
2838 ui.write(("* functions: %s\n") % ', '.join(sorted(funcs))) |
3373 ui.write("* functions: %s\n" % ', '.join(sorted(funcs))) |
2839 ui.write(t.renderdefault(props)) |
3374 ui.write(t.renderdefault(props)) |
2840 else: |
3375 else: |
2841 displayer = logcmdutil.maketemplater(ui, repo, tmpl) |
3376 displayer = logcmdutil.maketemplater(ui, repo, tmpl) |
2842 if ui.verbose: |
3377 if ui.verbose: |
2843 kwds, funcs = displayer.t.symbolsuseddefault() |
3378 kwds, funcs = displayer.t.symbolsuseddefault() |
2844 ui.write(("* keywords: %s\n") % ', '.join(sorted(kwds))) |
3379 ui.write("* keywords: %s\n" % ', '.join(sorted(kwds))) |
2845 ui.write(("* functions: %s\n") % ', '.join(sorted(funcs))) |
3380 ui.write("* functions: %s\n" % ', '.join(sorted(funcs))) |
2846 for r in revs: |
3381 for r in revs: |
2847 displayer.show(repo[r], **pycompat.strkwargs(props)) |
3382 displayer.show(repo[r], **pycompat.strkwargs(props)) |
2848 displayer.close() |
3383 displayer.close() |
2849 |
3384 |
2850 @command('debuguigetpass', [ |
3385 |
2851 ('p', 'prompt', '', _('prompt text'), _('TEXT')), |
3386 @command( |
2852 ], _('[-p TEXT]'), norepo=True) |
3387 'debuguigetpass', |
|
3388 [('p', 'prompt', '', _('prompt text'), _('TEXT')),], |
|
3389 _('[-p TEXT]'), |
|
3390 norepo=True, |
|
3391 ) |
2853 def debuguigetpass(ui, prompt=''): |
3392 def debuguigetpass(ui, prompt=''): |
2854 """show prompt to type password""" |
3393 """show prompt to type password""" |
2855 r = ui.getpass(prompt) |
3394 r = ui.getpass(prompt) |
2856 ui.write(('respose: %s\n') % r) |
3395 ui.write('respose: %s\n' % r) |
2857 |
3396 |
2858 @command('debuguiprompt', [ |
3397 |
2859 ('p', 'prompt', '', _('prompt text'), _('TEXT')), |
3398 @command( |
2860 ], _('[-p TEXT]'), norepo=True) |
3399 'debuguiprompt', |
|
3400 [('p', 'prompt', '', _('prompt text'), _('TEXT')),], |
|
3401 _('[-p TEXT]'), |
|
3402 norepo=True, |
|
3403 ) |
2861 def debuguiprompt(ui, prompt=''): |
3404 def debuguiprompt(ui, prompt=''): |
2862 """show plain prompt""" |
3405 """show plain prompt""" |
2863 r = ui.prompt(prompt) |
3406 r = ui.prompt(prompt) |
2864 ui.write(('response: %s\n') % r) |
3407 ui.write('response: %s\n' % r) |
|
3408 |
2865 |
3409 |
2866 @command('debugupdatecaches', []) |
3410 @command('debugupdatecaches', []) |
2867 def debugupdatecaches(ui, repo, *pats, **opts): |
3411 def debugupdatecaches(ui, repo, *pats, **opts): |
2868 """warm all known caches in the repository""" |
3412 """warm all known caches in the repository""" |
2869 with repo.wlock(), repo.lock(): |
3413 with repo.wlock(), repo.lock(): |
2870 repo.updatecaches(full=True) |
3414 repo.updatecaches(full=True) |
2871 |
3415 |
2872 @command('debugupgraderepo', [ |
3416 |
2873 ('o', 'optimize', [], _('extra optimization to perform'), _('NAME')), |
3417 @command( |
2874 ('', 'run', False, _('performs an upgrade')), |
3418 'debugupgraderepo', |
2875 ('', 'backup', True, _('keep the old repository content around')), |
3419 [ |
2876 ('', 'changelog', None, _('select the changelog for upgrade')), |
3420 ('o', 'optimize', [], _('extra optimization to perform'), _('NAME')), |
2877 ('', 'manifest', None, _('select the manifest for upgrade')), |
3421 ('', 'run', False, _('performs an upgrade')), |
2878 ]) |
3422 ('', 'backup', True, _('keep the old repository content around')), |
|
3423 ('', 'changelog', None, _('select the changelog for upgrade')), |
|
3424 ('', 'manifest', None, _('select the manifest for upgrade')), |
|
3425 ], |
|
3426 ) |
2879 def debugupgraderepo(ui, repo, run=False, optimize=None, backup=True, **opts): |
3427 def debugupgraderepo(ui, repo, run=False, optimize=None, backup=True, **opts): |
2880 """upgrade a repository to use different features |
3428 """upgrade a repository to use different features |
2881 |
3429 |
2882 If no arguments are specified, the repository is evaluated for upgrade |
3430 If no arguments are specified, the repository is evaluated for upgrade |
2883 and a list of problems and potential optimizations is printed. |
3431 and a list of problems and potential optimizations is printed. |
2901 * `--manifest`: only optimize the manifest |
3449 * `--manifest`: only optimize the manifest |
2902 * `--no-manifest`: optimize all revlog but the manifest |
3450 * `--no-manifest`: optimize all revlog but the manifest |
2903 * `--changelog`: optimize the changelog only |
3451 * `--changelog`: optimize the changelog only |
2904 * `--no-changelog --no-manifest`: optimize filelogs only |
3452 * `--no-changelog --no-manifest`: optimize filelogs only |
2905 """ |
3453 """ |
2906 return upgrade.upgraderepo(ui, repo, run=run, optimize=optimize, |
3454 return upgrade.upgraderepo( |
2907 backup=backup, **opts) |
3455 ui, repo, run=run, optimize=optimize, backup=backup, **opts |
2908 |
3456 ) |
2909 @command('debugwalk', cmdutil.walkopts, _('[OPTION]... [FILE]...'), |
3457 |
2910 inferrepo=True) |
3458 |
|
3459 @command( |
|
3460 'debugwalk', cmdutil.walkopts, _('[OPTION]... [FILE]...'), inferrepo=True |
|
3461 ) |
2911 def debugwalk(ui, repo, *pats, **opts): |
3462 def debugwalk(ui, repo, *pats, **opts): |
2912 """show how files match on given patterns""" |
3463 """show how files match on given patterns""" |
2913 opts = pycompat.byteskwargs(opts) |
3464 opts = pycompat.byteskwargs(opts) |
2914 m = scmutil.match(repo[None], pats, opts) |
3465 m = scmutil.match(repo[None], pats, opts) |
2915 if ui.verbose: |
3466 if ui.verbose: |
2916 ui.write(('* matcher:\n'), stringutil.prettyrepr(m), '\n') |
3467 ui.write('* matcher:\n', stringutil.prettyrepr(m), '\n') |
2917 items = list(repo[None].walk(m)) |
3468 items = list(repo[None].walk(m)) |
2918 if not items: |
3469 if not items: |
2919 return |
3470 return |
2920 f = lambda fn: fn |
3471 f = lambda fn: fn |
2921 if ui.configbool('ui', 'slash') and pycompat.ossep != '/': |
3472 if ui.configbool('ui', 'slash') and pycompat.ossep != '/': |
2922 f = lambda fn: util.normpath(fn) |
3473 f = lambda fn: util.normpath(fn) |
2923 fmt = 'f %%-%ds %%-%ds %%s' % ( |
3474 fmt = 'f %%-%ds %%-%ds %%s' % ( |
2924 max([len(abs) for abs in items]), |
3475 max([len(abs) for abs in items]), |
2925 max([len(repo.pathto(abs)) for abs in items])) |
3476 max([len(repo.pathto(abs)) for abs in items]), |
|
3477 ) |
2926 for abs in items: |
3478 for abs in items: |
2927 line = fmt % (abs, f(repo.pathto(abs)), m.exact(abs) and 'exact' or '') |
3479 line = fmt % (abs, f(repo.pathto(abs)), m.exact(abs) and 'exact' or '') |
2928 ui.write("%s\n" % line.rstrip()) |
3480 ui.write("%s\n" % line.rstrip()) |
|
3481 |
2929 |
3482 |
2930 @command('debugwhyunstable', [], _('REV')) |
3483 @command('debugwhyunstable', [], _('REV')) |
2931 def debugwhyunstable(ui, repo, rev): |
3484 def debugwhyunstable(ui, repo, rev): |
2932 """explain instabilities of a changeset""" |
3485 """explain instabilities of a changeset""" |
2933 for entry in obsutil.whyunstable(repo, scmutil.revsingle(repo, rev)): |
3486 for entry in obsutil.whyunstable(repo, scmutil.revsingle(repo, rev)): |
2934 dnodes = '' |
3487 dnodes = '' |
2935 if entry.get('divergentnodes'): |
3488 if entry.get('divergentnodes'): |
2936 dnodes = ' '.join('%s (%s)' % (ctx.hex(), ctx.phasestr()) |
3489 dnodes = ( |
2937 for ctx in entry['divergentnodes']) + ' ' |
3490 ' '.join( |
2938 ui.write('%s: %s%s %s\n' % (entry['instability'], dnodes, |
3491 '%s (%s)' % (ctx.hex(), ctx.phasestr()) |
2939 entry['reason'], entry['node'])) |
3492 for ctx in entry['divergentnodes'] |
2940 |
3493 ) |
2941 @command('debugwireargs', |
3494 + ' ' |
2942 [('', 'three', '', 'three'), |
3495 ) |
2943 ('', 'four', '', 'four'), |
3496 ui.write( |
2944 ('', 'five', '', 'five'), |
3497 '%s: %s%s %s\n' |
2945 ] + cmdutil.remoteopts, |
3498 % (entry['instability'], dnodes, entry['reason'], entry['node']) |
|
3499 ) |
|
3500 |
|
3501 |
|
3502 @command( |
|
3503 'debugwireargs', |
|
3504 [ |
|
3505 ('', 'three', '', 'three'), |
|
3506 ('', 'four', '', 'four'), |
|
3507 ('', 'five', '', 'five'), |
|
3508 ] |
|
3509 + cmdutil.remoteopts, |
2946 _('REPO [OPTIONS]... [ONE [TWO]]'), |
3510 _('REPO [OPTIONS]... [ONE [TWO]]'), |
2947 norepo=True) |
3511 norepo=True, |
|
3512 ) |
2948 def debugwireargs(ui, repopath, *vals, **opts): |
3513 def debugwireargs(ui, repopath, *vals, **opts): |
2949 opts = pycompat.byteskwargs(opts) |
3514 opts = pycompat.byteskwargs(opts) |
2950 repo = hg.peer(ui, opts, repopath) |
3515 repo = hg.peer(ui, opts, repopath) |
2951 for opt in cmdutil.remoteopts: |
3516 for opt in cmdutil.remoteopts: |
2952 del opts[opt[1]] |
3517 del opts[opt[1]] |
3001 |
3567 |
3002 # Flush last block. |
3568 # Flush last block. |
3003 if activeaction: |
3569 if activeaction: |
3004 yield activeaction, blocklines |
3570 yield activeaction, blocklines |
3005 |
3571 |
3006 @command('debugwireproto', |
3572 |
|
3573 @command( |
|
3574 'debugwireproto', |
3007 [ |
3575 [ |
3008 ('', 'localssh', False, _('start an SSH server for this repo')), |
3576 ('', 'localssh', False, _('start an SSH server for this repo')), |
3009 ('', 'peer', '', _('construct a specific version of the peer')), |
3577 ('', 'peer', '', _('construct a specific version of the peer')), |
3010 ('', 'noreadstderr', False, _('do not read from stderr of the remote')), |
3578 ('', 'noreadstderr', False, _('do not read from stderr of the remote')), |
3011 ('', 'nologhandshake', False, |
3579 ( |
3012 _('do not log I/O related to the peer handshake')), |
3580 '', |
3013 ] + cmdutil.remoteopts, |
3581 'nologhandshake', |
|
3582 False, |
|
3583 _('do not log I/O related to the peer handshake'), |
|
3584 ), |
|
3585 ] |
|
3586 + cmdutil.remoteopts, |
3014 _('[PATH]'), |
3587 _('[PATH]'), |
3015 optionalrepo=True) |
3588 optionalrepo=True, |
|
3589 ) |
3016 def debugwireproto(ui, repo, path=None, **opts): |
3590 def debugwireproto(ui, repo, path=None, **opts): |
3017 """send wire protocol commands to a server |
3591 """send wire protocol commands to a server |
3018 |
3592 |
3019 This command can be used to issue wire protocol commands to remote |
3593 This command can be used to issue wire protocol commands to remote |
3020 peers and to debug the raw data being exchanged. |
3594 peers and to debug the raw data being exchanged. |
3221 if opts['localssh']: |
3798 if opts['localssh']: |
3222 # We start the SSH server in its own process so there is process |
3799 # We start the SSH server in its own process so there is process |
3223 # separation. This prevents a whole class of potential bugs around |
3800 # separation. This prevents a whole class of potential bugs around |
3224 # shared state from interfering with server operation. |
3801 # shared state from interfering with server operation. |
3225 args = procutil.hgcmd() + [ |
3802 args = procutil.hgcmd() + [ |
3226 '-R', repo.root, |
3803 '-R', |
3227 'debugserve', '--sshstdio', |
3804 repo.root, |
|
3805 'debugserve', |
|
3806 '--sshstdio', |
3228 ] |
3807 ] |
3229 proc = subprocess.Popen(pycompat.rapply(procutil.tonativestr, args), |
3808 proc = subprocess.Popen( |
3230 stdin=subprocess.PIPE, |
3809 pycompat.rapply(procutil.tonativestr, args), |
3231 stdout=subprocess.PIPE, stderr=subprocess.PIPE, |
3810 stdin=subprocess.PIPE, |
3232 bufsize=0) |
3811 stdout=subprocess.PIPE, |
|
3812 stderr=subprocess.PIPE, |
|
3813 bufsize=0, |
|
3814 ) |
3233 |
3815 |
3234 stdin = proc.stdin |
3816 stdin = proc.stdin |
3235 stdout = proc.stdout |
3817 stdout = proc.stdout |
3236 stderr = proc.stderr |
3818 stderr = proc.stderr |
3237 |
3819 |
3238 # We turn the pipes into observers so we can log I/O. |
3820 # We turn the pipes into observers so we can log I/O. |
3239 if ui.verbose or opts['peer'] == 'raw': |
3821 if ui.verbose or opts['peer'] == 'raw': |
3240 stdin = util.makeloggingfileobject(ui, proc.stdin, b'i', |
3822 stdin = util.makeloggingfileobject( |
3241 logdata=True) |
3823 ui, proc.stdin, b'i', logdata=True |
3242 stdout = util.makeloggingfileobject(ui, proc.stdout, b'o', |
3824 ) |
3243 logdata=True) |
3825 stdout = util.makeloggingfileobject( |
3244 stderr = util.makeloggingfileobject(ui, proc.stderr, b'e', |
3826 ui, proc.stdout, b'o', logdata=True |
3245 logdata=True) |
3827 ) |
|
3828 stderr = util.makeloggingfileobject( |
|
3829 ui, proc.stderr, b'e', logdata=True |
|
3830 ) |
3246 |
3831 |
3247 # --localssh also implies the peer connection settings. |
3832 # --localssh also implies the peer connection settings. |
3248 |
3833 |
3249 url = 'ssh://localserver' |
3834 url = 'ssh://localserver' |
3250 autoreadstderr = not opts['noreadstderr'] |
3835 autoreadstderr = not opts['noreadstderr'] |
3251 |
3836 |
3252 if opts['peer'] == 'ssh1': |
3837 if opts['peer'] == 'ssh1': |
3253 ui.write(_('creating ssh peer for wire protocol version 1\n')) |
3838 ui.write(_('creating ssh peer for wire protocol version 1\n')) |
3254 peer = sshpeer.sshv1peer(ui, url, proc, stdin, stdout, stderr, |
3839 peer = sshpeer.sshv1peer( |
3255 None, autoreadstderr=autoreadstderr) |
3840 ui, |
|
3841 url, |
|
3842 proc, |
|
3843 stdin, |
|
3844 stdout, |
|
3845 stderr, |
|
3846 None, |
|
3847 autoreadstderr=autoreadstderr, |
|
3848 ) |
3256 elif opts['peer'] == 'ssh2': |
3849 elif opts['peer'] == 'ssh2': |
3257 ui.write(_('creating ssh peer for wire protocol version 2\n')) |
3850 ui.write(_('creating ssh peer for wire protocol version 2\n')) |
3258 peer = sshpeer.sshv2peer(ui, url, proc, stdin, stdout, stderr, |
3851 peer = sshpeer.sshv2peer( |
3259 None, autoreadstderr=autoreadstderr) |
3852 ui, |
|
3853 url, |
|
3854 proc, |
|
3855 stdin, |
|
3856 stdout, |
|
3857 stderr, |
|
3858 None, |
|
3859 autoreadstderr=autoreadstderr, |
|
3860 ) |
3260 elif opts['peer'] == 'raw': |
3861 elif opts['peer'] == 'raw': |
3261 ui.write(_('using raw connection to peer\n')) |
3862 ui.write(_('using raw connection to peer\n')) |
3262 peer = None |
3863 peer = None |
3263 else: |
3864 else: |
3264 ui.write(_('creating ssh peer from handshake results\n')) |
3865 ui.write(_('creating ssh peer from handshake results\n')) |
3265 peer = sshpeer.makepeer(ui, url, proc, stdin, stdout, stderr, |
3866 peer = sshpeer.makepeer( |
3266 autoreadstderr=autoreadstderr) |
3867 ui, |
|
3868 url, |
|
3869 proc, |
|
3870 stdin, |
|
3871 stdout, |
|
3872 stderr, |
|
3873 autoreadstderr=autoreadstderr, |
|
3874 ) |
3267 |
3875 |
3268 elif path: |
3876 elif path: |
3269 # We bypass hg.peer() so we can proxy the sockets. |
3877 # We bypass hg.peer() so we can proxy the sockets. |
3270 # TODO consider not doing this because we skip |
3878 # TODO consider not doing this because we skip |
3271 # ``hg.wirepeersetupfuncs`` and potentially other useful functionality. |
3879 # ``hg.wirepeersetupfuncs`` and potentially other useful functionality. |
3302 |
3909 |
3303 if opts['peer'] == 'http2': |
3910 if opts['peer'] == 'http2': |
3304 ui.write(_('creating http peer for wire protocol version 2\n')) |
3911 ui.write(_('creating http peer for wire protocol version 2\n')) |
3305 # We go through makepeer() because we need an API descriptor for |
3912 # We go through makepeer() because we need an API descriptor for |
3306 # the peer instance to be useful. |
3913 # the peer instance to be useful. |
3307 with ui.configoverride({ |
3914 with ui.configoverride( |
3308 ('experimental', 'httppeer.advertise-v2'): True}): |
3915 {('experimental', 'httppeer.advertise-v2'): True} |
|
3916 ): |
3309 if opts['nologhandshake']: |
3917 if opts['nologhandshake']: |
3310 ui.pushbuffer() |
3918 ui.pushbuffer() |
3311 |
3919 |
3312 peer = httppeer.makepeer(ui, path, opener=opener) |
3920 peer = httppeer.makepeer(ui, path, opener=opener) |
3313 |
3921 |
3314 if opts['nologhandshake']: |
3922 if opts['nologhandshake']: |
3315 ui.popbuffer() |
3923 ui.popbuffer() |
3316 |
3924 |
3317 if not isinstance(peer, httppeer.httpv2peer): |
3925 if not isinstance(peer, httppeer.httpv2peer): |
3318 raise error.Abort(_('could not instantiate HTTP peer for ' |
3926 raise error.Abort( |
3319 'wire protocol version 2'), |
3927 _( |
3320 hint=_('the server may not have the feature ' |
3928 'could not instantiate HTTP peer for ' |
3321 'enabled or is not allowing this ' |
3929 'wire protocol version 2' |
3322 'client version')) |
3930 ), |
|
3931 hint=_( |
|
3932 'the server may not have the feature ' |
|
3933 'enabled or is not allowing this ' |
|
3934 'client version' |
|
3935 ), |
|
3936 ) |
3323 |
3937 |
3324 elif opts['peer'] == 'raw': |
3938 elif opts['peer'] == 'raw': |
3325 ui.write(_('using raw connection to peer\n')) |
3939 ui.write(_('using raw connection to peer\n')) |
3326 peer = None |
3940 peer = None |
3327 elif opts['peer']: |
3941 elif opts['peer']: |
3328 raise error.Abort(_('--peer %s not supported with HTTP peers') % |
3942 raise error.Abort( |
3329 opts['peer']) |
3943 _('--peer %s not supported with HTTP peers') % opts['peer'] |
|
3944 ) |
3330 else: |
3945 else: |
3331 peer = httppeer.makepeer(ui, path, opener=opener) |
3946 peer = httppeer.makepeer(ui, path, opener=opener) |
3332 |
3947 |
3333 # We /could/ populate stdin/stdout with sock.makefile()... |
3948 # We /could/ populate stdin/stdout with sock.makefile()... |
3334 else: |
3949 else: |
3384 ui.status(_('sending %s command\n') % command) |
4003 ui.status(_('sending %s command\n') % command) |
3385 |
4004 |
3386 if 'PUSHFILE' in args: |
4005 if 'PUSHFILE' in args: |
3387 with open(args['PUSHFILE'], r'rb') as fh: |
4006 with open(args['PUSHFILE'], r'rb') as fh: |
3388 del args['PUSHFILE'] |
4007 del args['PUSHFILE'] |
3389 res, output = peer._callpush(command, fh, |
4008 res, output = peer._callpush( |
3390 **pycompat.strkwargs(args)) |
4009 command, fh, **pycompat.strkwargs(args) |
|
4010 ) |
3391 ui.status(_('result: %s\n') % stringutil.escapestr(res)) |
4011 ui.status(_('result: %s\n') % stringutil.escapestr(res)) |
3392 ui.status(_('remote output: %s\n') % |
4012 ui.status( |
3393 stringutil.escapestr(output)) |
4013 _('remote output: %s\n') % stringutil.escapestr(output) |
|
4014 ) |
3394 else: |
4015 else: |
3395 with peer.commandexecutor() as e: |
4016 with peer.commandexecutor() as e: |
3396 res = e.callcommand(command, args).result() |
4017 res = e.callcommand(command, args).result() |
3397 |
4018 |
3398 if isinstance(res, wireprotov2peer.commandresponse): |
4019 if isinstance(res, wireprotov2peer.commandresponse): |
3399 val = res.objects() |
4020 val = res.objects() |
3400 ui.status(_('response: %s\n') % |
4021 ui.status( |
3401 stringutil.pprint(val, bprefix=True, indent=2)) |
4022 _('response: %s\n') |
|
4023 % stringutil.pprint(val, bprefix=True, indent=2) |
|
4024 ) |
3402 else: |
4025 else: |
3403 ui.status(_('response: %s\n') % |
4026 ui.status( |
3404 stringutil.pprint(res, bprefix=True, indent=2)) |
4027 _('response: %s\n') |
|
4028 % stringutil.pprint(res, bprefix=True, indent=2) |
|
4029 ) |
3405 |
4030 |
3406 elif action == 'batchbegin': |
4031 elif action == 'batchbegin': |
3407 if batchedcommands is not None: |
4032 if batchedcommands is not None: |
3408 raise error.Abort(_('nested batchbegin not allowed')) |
4033 raise error.Abort(_('nested batchbegin not allowed')) |
3409 |
4034 |
3410 batchedcommands = [] |
4035 batchedcommands = [] |
3411 elif action == 'batchsubmit': |
4036 elif action == 'batchsubmit': |
3412 # There is a batching API we could go through. But it would be |
4037 # There is a batching API we could go through. But it would be |
3413 # difficult to normalize requests into function calls. It is easier |
4038 # difficult to normalize requests into function calls. It is easier |
3414 # to bypass this layer and normalize to commands + args. |
4039 # to bypass this layer and normalize to commands + args. |
3415 ui.status(_('sending batch with %d sub-commands\n') % |
4040 ui.status( |
3416 len(batchedcommands)) |
4041 _('sending batch with %d sub-commands\n') % len(batchedcommands) |
|
4042 ) |
3417 for i, chunk in enumerate(peer._submitbatch(batchedcommands)): |
4043 for i, chunk in enumerate(peer._submitbatch(batchedcommands)): |
3418 ui.status(_('response #%d: %s\n') % |
4044 ui.status( |
3419 (i, stringutil.escapestr(chunk))) |
4045 _('response #%d: %s\n') % (i, stringutil.escapestr(chunk)) |
|
4046 ) |
3420 |
4047 |
3421 batchedcommands = None |
4048 batchedcommands = None |
3422 |
4049 |
3423 elif action.startswith('httprequest '): |
4050 elif action.startswith('httprequest '): |
3424 if not opener: |
4051 if not opener: |
3425 raise error.Abort(_('cannot use httprequest without an HTTP ' |
4052 raise error.Abort( |
3426 'peer')) |
4053 _('cannot use httprequest without an HTTP ' 'peer') |
|
4054 ) |
3427 |
4055 |
3428 request = action.split(' ', 2) |
4056 request = action.split(' ', 2) |
3429 if len(request) != 3: |
4057 if len(request) != 3: |
3430 raise error.Abort(_('invalid httprequest: expected format is ' |
4058 raise error.Abort( |
3431 '"httprequest <method> <path>')) |
4059 _( |
|
4060 'invalid httprequest: expected format is ' |
|
4061 '"httprequest <method> <path>' |
|
4062 ) |
|
4063 ) |
3432 |
4064 |
3433 method, httppath = request[1:] |
4065 method, httppath = request[1:] |
3434 headers = {} |
4066 headers = {} |
3435 body = None |
4067 body = None |
3436 frames = [] |
4068 frames = [] |