Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/debugcommands.py @ 43076:2372284d9457
formatting: blacken the codebase
This is using my patch to black
(https://github.com/psf/black/pull/826) so we don't un-wrap collection
literals.
Done with:
hg files 'set:**.py - mercurial/thirdparty/** - "contrib/python-zstandard/**"' | xargs black -S
# skip-blame mass-reformatting only
# no-check-commit reformats foo_bar functions
Differential Revision: https://phab.mercurial-scm.org/D6971
author | Augie Fackler <augie@google.com> |
---|---|
date | Sun, 06 Oct 2019 09:45:02 -0400 |
parents | 0fde7d47ad6f |
children | 687b865b95ad |
comparison
equal
deleted
inserted
replaced
43075:57875cf423c9 | 43076:2372284d9457 |
---|---|
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 |
178 total += 1 | 193 total += 1 |
179 | 194 |
180 if mergeable_file: | 195 if mergeable_file: |
181 linesperrev = 2 | 196 linesperrev = 2 |
182 # make a file with k lines per rev | 197 # make a file with k lines per rev |
183 initialmergedlines = ['%d' % i | 198 initialmergedlines = [ |
184 for i in pycompat.xrange(0, total * linesperrev)] | 199 '%d' % i for i in pycompat.xrange(0, total * linesperrev) |
200 ] | |
185 initialmergedlines.append("") | 201 initialmergedlines.append("") |
186 | 202 |
187 tags = [] | 203 tags = [] |
188 progress = ui.makeprogress(_('building'), unit=_('revisions'), | 204 progress = ui.makeprogress(_('building'), unit=_('revisions'), total=total) |
189 total=total) | |
190 with progress, repo.wlock(), repo.lock(), repo.transaction("builddag"): | 205 with progress, repo.wlock(), repo.lock(), repo.transaction("builddag"): |
191 at = -1 | 206 at = -1 |
192 atbranch = 'default' | 207 atbranch = 'default' |
193 nodeids = [] | 208 nodeids = [] |
194 id = 0 | 209 id = 0 |
206 fn = "mf" | 221 fn = "mf" |
207 p1 = repo[ps[0]] | 222 p1 = repo[ps[0]] |
208 if len(ps) > 1: | 223 if len(ps) > 1: |
209 p2 = repo[ps[1]] | 224 p2 = repo[ps[1]] |
210 pa = p1.ancestor(p2) | 225 pa = p1.ancestor(p2) |
211 base, local, other = [x[fn].data() for x in (pa, p1, | 226 base, local, other = [ |
212 p2)] | 227 x[fn].data() for x in (pa, p1, p2) |
228 ] | |
213 m3 = simplemerge.Merge3Text(base, local, other) | 229 m3 = simplemerge.Merge3Text(base, local, other) |
214 ml = [l.strip() for l in m3.merge_lines()] | 230 ml = [l.strip() for l in m3.merge_lines()] |
215 ml.append("") | 231 ml.append("") |
216 elif at > 0: | 232 elif at > 0: |
217 ml = p1[fn].data().split("\n") | 233 ml = p1[fn].data().split("\n") |
239 files.append(fn) | 255 files.append(fn) |
240 filecontent[fn] = p2[fn].data() | 256 filecontent[fn] = p2[fn].data() |
241 | 257 |
242 def fctxfn(repo, cx, path): | 258 def fctxfn(repo, cx, path): |
243 if path in filecontent: | 259 if path in filecontent: |
244 return context.memfilectx(repo, cx, path, | 260 return context.memfilectx( |
245 filecontent[path]) | 261 repo, cx, path, filecontent[path] |
262 ) | |
246 return None | 263 return None |
247 | 264 |
248 if len(ps) == 0 or ps[0] < 0: | 265 if len(ps) == 0 or ps[0] < 0: |
249 pars = [None, None] | 266 pars = [None, None] |
250 elif len(ps) == 1: | 267 elif len(ps) == 1: |
251 pars = [nodeids[ps[0]], None] | 268 pars = [nodeids[ps[0]], None] |
252 else: | 269 else: |
253 pars = [nodeids[p] for p in ps] | 270 pars = [nodeids[p] for p in ps] |
254 cx = context.memctx(repo, pars, "r%i" % id, files, fctxfn, | 271 cx = context.memctx( |
255 date=(id, 0), | 272 repo, |
256 user="debugbuilddag", | 273 pars, |
257 extra={'branch': atbranch}) | 274 "r%i" % id, |
275 files, | |
276 fctxfn, | |
277 date=(id, 0), | |
278 user="debugbuilddag", | |
279 extra={'branch': atbranch}, | |
280 ) | |
258 nodeid = repo.commitctx(cx) | 281 nodeid = repo.commitctx(cx) |
259 nodeids.append(nodeid) | 282 nodeids.append(nodeid) |
260 at = id | 283 at = id |
261 elif type == 'l': | 284 elif type == 'l': |
262 id, name = data | 285 id, name = data |
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") |
296 raise error.Abort(_('use debugbundle2 for this file')) | 331 raise error.Abort(_('use debugbundle2 for this file')) |
297 chunkdata = gen.changelogheader() | 332 chunkdata = gen.changelogheader() |
298 for deltadata in gen.deltaiter(): | 333 for deltadata in gen.deltaiter(): |
299 node, p1, p2, cs, deltabase, delta, flags = deltadata | 334 node, p1, p2, cs, deltabase, delta, flags = deltadata |
300 ui.write("%s%s\n" % (indent_string, hex(node))) | 335 ui.write("%s%s\n" % (indent_string, hex(node))) |
336 | |
301 | 337 |
302 def _debugobsmarkers(ui, part, indent=0, **opts): | 338 def _debugobsmarkers(ui, part, indent=0, **opts): |
303 """display version and markers contained in 'data'""" | 339 """display version and markers contained in 'data'""" |
304 opts = pycompat.byteskwargs(opts) | 340 opts = pycompat.byteskwargs(opts) |
305 data = part.read() | 341 data = part.read() |
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(): |
448 ui._styles[k] = k[6:] | 498 ui._styles[k] = k[6:] |
449 elif k.startswith('terminfo.'): | 499 elif k.startswith('terminfo.'): |
450 ui._styles[k] = k[9:] | 500 ui._styles[k] = k[9:] |
451 ui.write(_('available colors:\n')) | 501 ui.write(_('available colors:\n')) |
452 # sort label with a '_' after the other to group '_background' entry. | 502 # sort label with a '_' after the other to group '_background' entry. |
453 items = sorted(ui._styles.items(), | 503 items = sorted(ui._styles.items(), key=lambda i: ('_' in i[0], i[0], i[1])) |
454 key=lambda i: ('_' in i[0], i[0], i[1])) | |
455 for colorname, label in items: | 504 for colorname, label in items: |
456 ui.write(('%s\n') % colorname, label=label) | 505 ui.write('%s\n' % colorname, label=label) |
506 | |
457 | 507 |
458 def _debugdisplaystyle(ui): | 508 def _debugdisplaystyle(ui): |
459 ui.write(_('available style:\n')) | 509 ui.write(_('available style:\n')) |
460 if not ui._styles: | 510 if not ui._styles: |
461 return | 511 return |
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 |
659 | 730 |
660 return compsize, uncompsize, deltatype, chain, chainsize | 731 return compsize, uncompsize, deltatype, chain, chainsize |
661 | 732 |
662 fm = ui.formatter('debugdeltachain', opts) | 733 fm = ui.formatter('debugdeltachain', opts) |
663 | 734 |
664 fm.plain(' rev chain# chainlen prev delta ' | 735 fm.plain( |
665 'size rawsize chainsize ratio lindist extradist ' | 736 ' rev chain# chainlen prev delta ' |
666 'extraratio') | 737 'size rawsize chainsize ratio lindist extradist ' |
738 'extraratio' | |
739 ) | |
667 if withsparseread: | 740 if withsparseread: |
668 fm.plain(' readsize largestblk rddensity srchunks') | 741 fm.plain(' readsize largestblk rddensity srchunks') |
669 fm.plain('\n') | 742 fm.plain('\n') |
670 | 743 |
671 chainbases = {} | 744 chainbases = {} |
691 extraratio = float(extradist) / float(chainsize) | 764 extraratio = float(extradist) / float(chainsize) |
692 else: | 765 else: |
693 extraratio = extradist | 766 extraratio = extradist |
694 | 767 |
695 fm.startitem() | 768 fm.startitem() |
696 fm.write('rev chainid chainlen prevrev deltatype compsize ' | 769 fm.write( |
697 'uncompsize chainsize chainratio lindist extradist ' | 770 'rev chainid chainlen prevrev deltatype compsize ' |
698 'extraratio', | 771 'uncompsize chainsize chainratio lindist extradist ' |
699 '%7d %7d %8d %8d %7s %10d %10d %10d %9.5f %9d %9d %10.5f', | 772 'extraratio', |
700 rev, chainid, len(chain), prevrev, deltatype, comp, | 773 '%7d %7d %8d %8d %7s %10d %10d %10d %9.5f %9d %9d %10.5f', |
701 uncomp, chainsize, chainratio, lineardist, extradist, | 774 rev, |
702 extraratio, | 775 chainid, |
703 rev=rev, chainid=chainid, chainlen=len(chain), | 776 len(chain), |
704 prevrev=prevrev, deltatype=deltatype, compsize=comp, | 777 prevrev, |
705 uncompsize=uncomp, chainsize=chainsize, | 778 deltatype, |
706 chainratio=chainratio, lindist=lineardist, | 779 comp, |
707 extradist=extradist, extraratio=extraratio) | 780 uncomp, |
781 chainsize, | |
782 chainratio, | |
783 lineardist, | |
784 extradist, | |
785 extraratio, | |
786 rev=rev, | |
787 chainid=chainid, | |
788 chainlen=len(chain), | |
789 prevrev=prevrev, | |
790 deltatype=deltatype, | |
791 compsize=comp, | |
792 uncompsize=uncomp, | |
793 chainsize=chainsize, | |
794 chainratio=chainratio, | |
795 lindist=lineardist, | |
796 extradist=extradist, | |
797 extraratio=extraratio, | |
798 ) | |
708 if withsparseread: | 799 if withsparseread: |
709 readsize = 0 | 800 readsize = 0 |
710 largestblock = 0 | 801 largestblock = 0 |
711 srchunks = 0 | 802 srchunks = 0 |
712 | 803 |
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 |
880 dest.write(data) | 997 dest.write(data) |
881 data = fh.read(_chunksize) | 998 data = fh.read(_chunksize) |
882 finally: | 999 finally: |
883 if output: | 1000 if output: |
884 dest.close() | 1001 dest.close() |
1002 | |
885 | 1003 |
886 @command('debugextensions', cmdutil.formatteropts, [], optionalrepo=True) | 1004 @command('debugextensions', cmdutil.formatteropts, [], optionalrepo=True) |
887 def debugextensions(ui, repo, **opts): | 1005 def debugextensions(ui, repo, **opts): |
888 '''show information about active extensions''' | 1006 '''show information about active extensions''' |
889 opts = pycompat.byteskwargs(opts) | 1007 opts = pycompat.byteskwargs(opts) |
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.""" |
1010 def makeformatname(name): | 1163 def makeformatname(name): |
1011 return '%s:' + (' ' * (maxvariantlength - len(name))) | 1164 return '%s:' + (' ' * (maxvariantlength - len(name))) |
1012 | 1165 |
1013 fm = ui.formatter('debugformat', opts) | 1166 fm = ui.formatter('debugformat', opts) |
1014 if fm.isplain(): | 1167 if fm.isplain(): |
1168 | |
1015 def formatvalue(value): | 1169 def formatvalue(value): |
1016 if util.safehasattr(value, 'startswith'): | 1170 if util.safehasattr(value, 'startswith'): |
1017 return value | 1171 return value |
1018 if value: | 1172 if value: |
1019 return 'yes' | 1173 return 'yes' |
1020 else: | 1174 else: |
1021 return 'no' | 1175 return 'no' |
1176 | |
1022 else: | 1177 else: |
1023 formatvalue = pycompat.identity | 1178 formatvalue = pycompat.identity |
1024 | 1179 |
1025 fm.plain('format-variant') | 1180 fm.plain('format-variant') |
1026 fm.plain(' ' * (maxvariantlength - len('format-variant'))) | 1181 fm.plain(' ' * (maxvariantlength - len('format-variant'))) |
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. |
1099 # TODO: get desired bundlecaps from command line. | 1268 # TODO: get desired bundlecaps from command line. |
1100 args[r'bundlecaps'] = None | 1269 args[r'bundlecaps'] = None |
1101 bundle = repo.getbundle('debug', **args) | 1270 bundle = repo.getbundle('debug', **args) |
1102 | 1271 |
1103 bundletype = opts.get('type', 'bzip2').lower() | 1272 bundletype = opts.get('type', 'bzip2').lower() |
1104 btypes = {'none': 'HG10UN', | 1273 btypes = { |
1105 'bzip2': 'HG10BZ', | 1274 'none': 'HG10UN', |
1106 'gzip': 'HG10GZ', | 1275 'bzip2': 'HG10BZ', |
1107 'bundle2': 'HG20'} | 1276 'gzip': 'HG10GZ', |
1277 'bundle2': 'HG20', | |
1278 } | |
1108 bundletype = btypes.get(bundletype) | 1279 bundletype = btypes.get(bundletype) |
1109 if bundletype not in bundle2.bundletypes: | 1280 if bundletype not in bundle2.bundletypes: |
1110 raise error.Abort(_('unknown bundle type specified with --type')) | 1281 raise error.Abort(_('unknown bundle type specified with --type')) |
1111 bundle2.writebundle(ui, bundle, bundlepath, bundletype) | 1282 bundle2.writebundle(ui, bundle, bundlepath, bundletype) |
1283 | |
1112 | 1284 |
1113 @command('debugignore', [], '[FILE]') | 1285 @command('debugignore', [], '[FILE]') |
1114 def debugignore(ui, repo, *files, **opts): | 1286 def debugignore(ui, repo, *files, **opts): |
1115 """display the combined ignore pattern and information about ignored files | 1287 """display the combined ignore pattern and information about ignored files |
1116 | 1288 |
1142 break | 1314 break |
1143 if ignored: | 1315 if ignored: |
1144 if ignored == nf: | 1316 if ignored == nf: |
1145 ui.write(_("%s is ignored\n") % uipathfn(f)) | 1317 ui.write(_("%s is ignored\n") % uipathfn(f)) |
1146 else: | 1318 else: |
1147 ui.write(_("%s is ignored because of " | 1319 ui.write( |
1148 "containing directory %s\n") | 1320 _( |
1149 % (uipathfn(f), ignored)) | 1321 "%s is ignored because of " |
1322 "containing directory %s\n" | |
1323 ) | |
1324 % (uipathfn(f), ignored) | |
1325 ) | |
1150 ignorefile, lineno, line = ignoredata | 1326 ignorefile, lineno, line = ignoredata |
1151 ui.write(_("(ignore rule in %s, line %d: '%s')\n") | 1327 ui.write( |
1152 % (ignorefile, lineno, line)) | 1328 _("(ignore rule in %s, line %d: '%s')\n") |
1329 % (ignorefile, lineno, line) | |
1330 ) | |
1153 else: | 1331 else: |
1154 ui.write(_("%s is not ignored\n") % uipathfn(f)) | 1332 ui.write(_("%s is not ignored\n") % uipathfn(f)) |
1155 | 1333 |
1156 @command('debugindex', cmdutil.debugrevlogopts + cmdutil.formatteropts, | 1334 |
1157 _('-c|-m|FILE')) | 1335 @command( |
1336 'debugindex', | |
1337 cmdutil.debugrevlogopts + cmdutil.formatteropts, | |
1338 _('-c|-m|FILE'), | |
1339 ) | |
1158 def debugindex(ui, repo, file_=None, **opts): | 1340 def debugindex(ui, repo, file_=None, **opts): |
1159 """dump index data for a storage primitive""" | 1341 """dump index data for a storage primitive""" |
1160 opts = pycompat.byteskwargs(opts) | 1342 opts = pycompat.byteskwargs(opts) |
1161 store = cmdutil.openstorage(repo, 'debugindex', file_, opts) | 1343 store = cmdutil.openstorage(repo, 'debugindex', file_, opts) |
1162 | 1344 |
1169 for i in store: | 1351 for i in store: |
1170 idlen = len(shortfn(store.node(i))) | 1352 idlen = len(shortfn(store.node(i))) |
1171 break | 1353 break |
1172 | 1354 |
1173 fm = ui.formatter('debugindex', opts) | 1355 fm = ui.formatter('debugindex', opts) |
1174 fm.plain(b' rev linkrev %s %s p2\n' % ( | 1356 fm.plain( |
1175 b'nodeid'.ljust(idlen), | 1357 b' rev linkrev %s %s p2\n' |
1176 b'p1'.ljust(idlen))) | 1358 % (b'nodeid'.ljust(idlen), b'p1'.ljust(idlen)) |
1359 ) | |
1177 | 1360 |
1178 for rev in store: | 1361 for rev in store: |
1179 node = store.node(rev) | 1362 node = store.node(rev) |
1180 parents = store.parents(node) | 1363 parents = store.parents(node) |
1181 | 1364 |
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) |
1212 if not util.safehasattr(index, 'stats'): | 1398 if not util.safehasattr(index, 'stats'): |
1213 raise error.Abort(_('debugindexstats only works with native code')) | 1399 raise error.Abort(_('debugindexstats only works with native code')) |
1214 for k, v in sorted(index.stats().items()): | 1400 for k, v in sorted(index.stats().items()): |
1215 ui.write('%s: %d\n' % (k, v)) | 1401 ui.write('%s: %d\n' % (k, v)) |
1216 | 1402 |
1403 | |
1217 @command('debuginstall', [] + cmdutil.formatteropts, '', norepo=True) | 1404 @command('debuginstall', [] + cmdutil.formatteropts, '', norepo=True) |
1218 def debuginstall(ui, **opts): | 1405 def debuginstall(ui, **opts): |
1219 '''test Mercurial installation | 1406 '''test Mercurial installation |
1220 | 1407 |
1221 Returns 0 on success. | 1408 Returns 0 on success. |
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 |
1716 n = bin(s) | 2041 n = bin(s) |
1717 if len(n) != len(nullid): | 2042 if len(n) != len(nullid): |
1718 raise TypeError() | 2043 raise TypeError() |
1719 return n | 2044 return n |
1720 except TypeError: | 2045 except TypeError: |
1721 raise error.Abort('changeset references must be full hexadecimal ' | 2046 raise error.Abort( |
1722 'node identifiers') | 2047 'changeset references must be full hexadecimal ' |
2048 'node identifiers' | |
2049 ) | |
1723 | 2050 |
1724 if opts.get('delete'): | 2051 if opts.get('delete'): |
1725 indices = [] | 2052 indices = [] |
1726 for v in opts.get('delete'): | 2053 for v in opts.get('delete'): |
1727 try: | 2054 try: |
1728 indices.append(int(v)) | 2055 indices.append(int(v)) |
1729 except ValueError: | 2056 except ValueError: |
1730 raise error.Abort(_('invalid index value: %r') % v, | 2057 raise error.Abort( |
1731 hint=_('use integers for indices')) | 2058 _('invalid index value: %r') % v, |
2059 hint=_('use integers for indices'), | |
2060 ) | |
1732 | 2061 |
1733 if repo.currenttransaction(): | 2062 if repo.currenttransaction(): |
1734 raise error.Abort(_('cannot delete obsmarkers in the middle ' | 2063 raise error.Abort( |
1735 'of transaction.')) | 2064 _('cannot delete obsmarkers in the middle ' 'of transaction.') |
2065 ) | |
1736 | 2066 |
1737 with repo.lock(): | 2067 with repo.lock(): |
1738 n = repair.deleteobsmarkers(repo.obsstore, indices) | 2068 n = repair.deleteobsmarkers(repo.obsstore, indices) |
1739 ui.write(_('deleted %i obsolescence markers\n') % n) | 2069 ui.write(_('deleted %i obsolescence markers\n') % n) |
1740 | 2070 |
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. |
1850 rootdir = repo.root + pycompat.ossep | 2204 rootdir = repo.root + pycompat.ossep |
1851 if spec != repo.root and not spec.startswith(rootdir): | 2205 if spec != repo.root and not spec.startswith(rootdir): |
1852 return [], [] | 2206 return [], [] |
1853 if os.path.isdir(spec): | 2207 if os.path.isdir(spec): |
1854 spec += '/' | 2208 spec += '/' |
1855 spec = spec[len(rootdir):] | 2209 spec = spec[len(rootdir) :] |
1856 fixpaths = pycompat.ossep != '/' | 2210 fixpaths = pycompat.ossep != '/' |
1857 if fixpaths: | 2211 if fixpaths: |
1858 spec = spec.replace(pycompat.ossep, '/') | 2212 spec = spec.replace(pycompat.ossep, '/') |
1859 speclen = len(spec) | 2213 speclen = len(spec) |
1860 fullpaths = opts[r'full'] | 2214 fullpaths = opts[r'full'] |
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 |
1923 | 2281 |
1924 ui.write(_('url: %s\n') % peer.url()) | 2282 ui.write(_('url: %s\n') % peer.url()) |
1925 ui.write(_('local: %s\n') % (_('yes') if local else _('no'))) | 2283 ui.write(_('local: %s\n') % (_('yes') if local else _('no'))) |
1926 ui.write(_('pushable: %s\n') % (_('yes') if canpush else _('no'))) | 2284 ui.write(_('pushable: %s\n') % (_('yes') if canpush else _('no'))) |
1927 | 2285 |
1928 @command('debugpickmergetool', | 2286 |
1929 [('r', 'rev', '', _('check for files in this revision'), _('REV')), | 2287 @command( |
1930 ('', 'changedelete', None, _('emulate merging change and delete')), | 2288 'debugpickmergetool', |
1931 ] + cmdutil.walkopts + cmdutil.mergetoolopts, | 2289 [ |
1932 _('[PATTERN]...'), | 2290 ('r', 'rev', '', _('check for files in this revision'), _('REV')), |
1933 inferrepo=True) | 2291 ('', 'changedelete', None, _('emulate merging change and delete')), |
2292 ] | |
2293 + cmdutil.walkopts | |
2294 + cmdutil.mergetoolopts, | |
2295 _('[PATTERN]...'), | |
2296 inferrepo=True, | |
2297 ) | |
1934 def debugpickmergetool(ui, repo, *pats, **opts): | 2298 def debugpickmergetool(ui, repo, *pats, **opts): |
1935 """examine which merge tool is chosen for specified file | 2299 """examine which merge tool is chosen for specified file |
1936 | 2300 |
1937 As described in :hg:`help merge-tools`, Mercurial examines | 2301 As described in :hg:`help merge-tools`, Mercurial examines |
1938 configurations below in this order to decide which merge tool is | 2302 configurations below in this order to decide which merge tool is |
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 |
2016 | 2385 |
2017 target = hg.peer(ui, {}, repopath) | 2386 target = hg.peer(ui, {}, repopath) |
2018 if keyinfo: | 2387 if keyinfo: |
2019 key, old, new = keyinfo | 2388 key, old, new = keyinfo |
2020 with target.commandexecutor() as e: | 2389 with target.commandexecutor() as e: |
2021 r = e.callcommand('pushkey', { | 2390 r = e.callcommand( |
2022 'namespace': namespace, | 2391 'pushkey', |
2023 'key': key, | 2392 {'namespace': namespace, 'key': key, 'old': old, 'new': new,}, |
2024 'old': old, | 2393 ).result() |
2025 'new': new, | |
2026 }).result() | |
2027 | 2394 |
2028 ui.status(pycompat.bytestr(r) + '\n') | 2395 ui.status(pycompat.bytestr(r) + '\n') |
2029 return not r | 2396 return not r |
2030 else: | 2397 else: |
2031 for k, v in sorted(target.listkeys(namespace).iteritems()): | 2398 for k, v in sorted(target.listkeys(namespace).iteritems()): |
2032 ui.write("%s\t%s\n" % (stringutil.escapestr(k), | 2399 ui.write( |
2033 stringutil.escapestr(v))) | 2400 "%s\t%s\n" % (stringutil.escapestr(k), stringutil.escapestr(v)) |
2401 ) | |
2402 | |
2034 | 2403 |
2035 @command('debugpvec', [], _('A B')) | 2404 @command('debugpvec', [], _('A B')) |
2036 def debugpvec(ui, repo, a, b=None): | 2405 def debugpvec(ui, repo, a, b=None): |
2037 ca = scmutil.revsingle(repo, a) | 2406 ca = scmutil.revsingle(repo, a) |
2038 cb = scmutil.revsingle(repo, b) | 2407 cb = scmutil.revsingle(repo, b) |
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')) |
2112 if o: | 2502 if o: |
2113 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1]))) | 2503 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1]))) |
2114 else: | 2504 else: |
2115 ui.write(_("%s not renamed\n") % rel) | 2505 ui.write(_("%s not renamed\n") % rel) |
2116 | 2506 |
2117 @command('debugrevlog', cmdutil.debugrevlogopts + | 2507 |
2118 [('d', 'dump', False, _('dump index data'))], | 2508 @command( |
2509 'debugrevlog', | |
2510 cmdutil.debugrevlogopts + [('d', 'dump', False, _('dump index data'))], | |
2119 _('-c|-m|FILE'), | 2511 _('-c|-m|FILE'), |
2120 optionalrepo=True) | 2512 optionalrepo=True, |
2513 ) | |
2121 def debugrevlog(ui, repo, file_=None, **opts): | 2514 def debugrevlog(ui, repo, file_=None, **opts): |
2122 """show data and statistics about a revlog""" | 2515 """show data and statistics about a revlog""" |
2123 opts = pycompat.byteskwargs(opts) | 2516 opts = pycompat.byteskwargs(opts) |
2124 r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts) | 2517 r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts) |
2125 | 2518 |
2126 if opts.get("dump"): | 2519 if opts.get("dump"): |
2127 numrevs = len(r) | 2520 numrevs = len(r) |
2128 ui.write(("# rev p1rev p2rev start end deltastart base p1 p2" | 2521 ui.write( |
2129 " rawsize totalsize compression heads chainlen\n")) | 2522 ( |
2523 "# rev p1rev p2rev start end deltastart base p1 p2" | |
2524 " rawsize totalsize compression heads chainlen\n" | |
2525 ) | |
2526 ) | |
2130 ts = 0 | 2527 ts = 0 |
2131 heads = set() | 2528 heads = set() |
2132 | 2529 |
2133 for rev in pycompat.xrange(numrevs): | 2530 for rev in pycompat.xrange(numrevs): |
2134 dbase = r.deltaparent(rev) | 2531 dbase = r.deltaparent(rev) |
2143 heads.add(rev) | 2540 heads.add(rev) |
2144 try: | 2541 try: |
2145 compression = ts / r.end(rev) | 2542 compression = ts / r.end(rev) |
2146 except ZeroDivisionError: | 2543 except ZeroDivisionError: |
2147 compression = 0 | 2544 compression = 0 |
2148 ui.write("%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d " | 2545 ui.write( |
2149 "%11d %5d %8d\n" % | 2546 "%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d " |
2150 (rev, p1, p2, r.start(rev), r.end(rev), | 2547 "%11d %5d %8d\n" |
2151 r.start(dbase), r.start(cbase), | 2548 % ( |
2152 r.start(p1), r.start(p2), | 2549 rev, |
2153 rs, ts, compression, len(heads), clen)) | 2550 p1, |
2551 p2, | |
2552 r.start(rev), | |
2553 r.end(rev), | |
2554 r.start(dbase), | |
2555 r.start(cbase), | |
2556 r.start(p1), | |
2557 r.start(p2), | |
2558 rs, | |
2559 ts, | |
2560 compression, | |
2561 len(heads), | |
2562 clen, | |
2563 ) | |
2564 ) | |
2154 return 0 | 2565 return 0 |
2155 | 2566 |
2156 v = r.version | 2567 v = r.version |
2157 format = v & 0xFFFF | 2568 format = v & 0xFFFF |
2158 flags = [] | 2569 flags = [] |
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. |
2507 """ | 3006 """ |
2508 opts = pycompat.byteskwargs(opts) | 3007 opts = pycompat.byteskwargs(opts) |
2509 aliases = ui.configitems('revsetalias') | 3008 aliases = ui.configitems('revsetalias') |
2510 stages = [ | 3009 stages = [ |
2511 ('parsed', lambda tree: tree), | 3010 ('parsed', lambda tree: tree), |
2512 ('expanded', lambda tree: revsetlang.expandaliases(tree, aliases, | 3011 ( |
2513 ui.warn)), | 3012 'expanded', |
3013 lambda tree: revsetlang.expandaliases(tree, aliases, ui.warn), | |
3014 ), | |
2514 ('concatenated', revsetlang.foldconcat), | 3015 ('concatenated', revsetlang.foldconcat), |
2515 ('analyzed', revsetlang.analyze), | 3016 ('analyzed', revsetlang.analyze), |
2516 ('optimized', revsetlang.optimize), | 3017 ('optimized', revsetlang.optimize), |
2517 ] | 3018 ] |
2518 if opts['no_optimized']: | 3019 if opts['no_optimized']: |
2519 stages = stages[:-1] | 3020 stages = stages[:-1] |
2520 if opts['verify_optimized'] and opts['no_optimized']: | 3021 if opts['verify_optimized'] and opts['no_optimized']: |
2521 raise error.Abort(_('cannot use --verify-optimized with ' | 3022 raise error.Abort( |
2522 '--no-optimized')) | 3023 _('cannot use --verify-optimized with ' '--no-optimized') |
3024 ) | |
2523 stagenames = set(n for n, f in stages) | 3025 stagenames = set(n for n, f in stages) |
2524 | 3026 |
2525 showalways = set() | 3027 showalways = set() |
2526 showchanged = set() | 3028 showchanged = set() |
2527 if ui.verbose and not opts['show_stage']: | 3029 if ui.verbose and not opts['show_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') |
2577 return 1 | 3079 return 1 |
2578 | 3080 |
2579 func = revset.makematcher(tree) | 3081 func = revset.makematcher(tree) |
2580 revs = func(repo) | 3082 revs = func(repo) |
2581 if opts['show_set'] or (opts['show_set'] is None and ui.verbose): | 3083 if opts['show_set'] or (opts['show_set'] is None and ui.verbose): |
2582 ui.write(("* set:\n"), stringutil.prettyrepr(revs), "\n") | 3084 ui.write("* set:\n", stringutil.prettyrepr(revs), "\n") |
2583 if not opts['show_revs']: | 3085 if not opts['show_revs']: |
2584 return | 3086 return |
2585 for c in revs: | 3087 for c in revs: |
2586 ui.write("%d\n" % c) | 3088 ui.write("%d\n" % c) |
2587 | 3089 |
2588 @command('debugserve', [ | 3090 |
2589 ('', 'sshstdio', False, _('run an SSH server bound to process handles')), | 3091 @command( |
2590 ('', 'logiofd', '', _('file descriptor to log server I/O to')), | 3092 'debugserve', |
2591 ('', 'logiofile', '', _('file to log server I/O to')), | 3093 [ |
2592 ], '') | 3094 ( |
3095 '', | |
3096 'sshstdio', | |
3097 False, | |
3098 _('run an SSH server bound to process handles'), | |
3099 ), | |
3100 ('', 'logiofd', '', _('file descriptor to log server I/O to')), | |
3101 ('', 'logiofile', '', _('file to log server I/O to')), | |
3102 ], | |
3103 '', | |
3104 ) | |
2593 def debugserve(ui, repo, **opts): | 3105 def debugserve(ui, repo, **opts): |
2594 """run a server with advanced settings | 3106 """run a server with advanced settings |
2595 | 3107 |
2596 This command is similar to :hg:`serve`. It exists partially as a | 3108 This command is similar to :hg:`serve`. It exists partially as a |
2597 workaround to the fact that ``hg serve --stdio`` must have specific | 3109 workaround to the fact that ``hg serve --stdio`` must have specific |
2620 logfh = open(opts['logiofile'], 'ab', 1) | 3132 logfh = open(opts['logiofile'], 'ab', 1) |
2621 | 3133 |
2622 s = wireprotoserver.sshserver(ui, repo, logfh=logfh) | 3134 s = wireprotoserver.sshserver(ui, repo, logfh=logfh) |
2623 s.serve_forever() | 3135 s.serve_forever() |
2624 | 3136 |
3137 | |
2625 @command('debugsetparents', [], _('REV1 [REV2]')) | 3138 @command('debugsetparents', [], _('REV1 [REV2]')) |
2626 def debugsetparents(ui, repo, rev1, rev2=None): | 3139 def debugsetparents(ui, repo, rev1, rev2=None): |
2627 """manually set the parents of the current working directory | 3140 """manually set the parents of the current working directory |
2628 | 3141 |
2629 This is useful for writing repository conversion tools, but should | 3142 This is useful for writing repository conversion tools, but should |
2637 node1 = scmutil.revsingle(repo, rev1).node() | 3150 node1 = scmutil.revsingle(repo, rev1).node() |
2638 node2 = scmutil.revsingle(repo, rev2, 'null').node() | 3151 node2 = scmutil.revsingle(repo, rev2, 'null').node() |
2639 | 3152 |
2640 with repo.wlock(): | 3153 with repo.wlock(): |
2641 repo.setparents(node1, node2) | 3154 repo.setparents(node1, node2) |
3155 | |
2642 | 3156 |
2643 @command('debugsidedata', cmdutil.debugrevlogopts, _('-c|-m|FILE REV')) | 3157 @command('debugsidedata', cmdutil.debugrevlogopts, _('-c|-m|FILE REV')) |
2644 def debugsidedata(ui, repo, file_, rev=None, **opts): | 3158 def debugsidedata(ui, repo, file_, rev=None, **opts): |
2645 """dump the side data for a cl/manifest/file revision""" | 3159 """dump the side data for a cl/manifest/file revision""" |
2646 opts = pycompat.byteskwargs(opts) | 3160 opts = pycompat.byteskwargs(opts) |
2663 for key, value in sidedata: | 3177 for key, value in sidedata: |
2664 ui.write((' entry-%04o size %d\n' % (key, len(value)))) | 3178 ui.write((' entry-%04o size %d\n' % (key, len(value)))) |
2665 if ui.verbose: | 3179 if ui.verbose: |
2666 ui.write((' %s\n' % stringutil.pprint(value))) | 3180 ui.write((' %s\n' % stringutil.pprint(value))) |
2667 | 3181 |
3182 | |
2668 @command('debugssl', [], '[SOURCE]', optionalrepo=True) | 3183 @command('debugssl', [], '[SOURCE]', optionalrepo=True) |
2669 def debugssl(ui, repo, source=None, **opts): | 3184 def debugssl(ui, repo, source=None, **opts): |
2670 '''test a secure connection to a server | 3185 '''test a secure connection to a server |
2671 | 3186 |
2672 This builds the certificate chain for the server on Windows, installing the | 3187 This builds the certificate chain for the server on Windows, installing the |
2678 | 3193 |
2679 If the update succeeds, retry the original operation. Otherwise, the cause | 3194 If the update succeeds, retry the original operation. Otherwise, the cause |
2680 of the SSL error is likely another issue. | 3195 of the SSL error is likely another issue. |
2681 ''' | 3196 ''' |
2682 if not pycompat.iswindows: | 3197 if not pycompat.iswindows: |
2683 raise error.Abort(_('certificate chain building is only possible on ' | 3198 raise error.Abort( |
2684 'Windows')) | 3199 _('certificate chain building is only possible on ' 'Windows') |
3200 ) | |
2685 | 3201 |
2686 if not source: | 3202 if not source: |
2687 if not repo: | 3203 if not repo: |
2688 raise error.Abort(_("there is no Mercurial repository here, and no " | 3204 raise error.Abort( |
2689 "server specified")) | 3205 _( |
3206 "there is no Mercurial repository here, and no " | |
3207 "server specified" | |
3208 ) | |
3209 ) | |
2690 source = "default" | 3210 source = "default" |
2691 | 3211 |
2692 source, branches = hg.parseurl(ui.expandpath(source)) | 3212 source, branches = hg.parseurl(ui.expandpath(source)) |
2693 url = util.url(source) | 3213 url = util.url(source) |
2694 | 3214 |
2701 else: | 3221 else: |
2702 raise error.Abort(_("only https and ssh connections are supported")) | 3222 raise error.Abort(_("only https and ssh connections are supported")) |
2703 | 3223 |
2704 from . import win32 | 3224 from . import win32 |
2705 | 3225 |
2706 s = ssl.wrap_socket(socket.socket(), ssl_version=ssl.PROTOCOL_TLS, | 3226 s = ssl.wrap_socket( |
2707 cert_reqs=ssl.CERT_NONE, ca_certs=None) | 3227 socket.socket(), |
3228 ssl_version=ssl.PROTOCOL_TLS, | |
3229 cert_reqs=ssl.CERT_NONE, | |
3230 ca_certs=None, | |
3231 ) | |
2708 | 3232 |
2709 try: | 3233 try: |
2710 s.connect(addr) | 3234 s.connect(addr) |
2711 cert = s.getpeercert(True) | 3235 cert = s.getpeercert(True) |
2712 | 3236 |
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 |
2805 Use --verbose to print the parsed tree. | 3339 Use --verbose to print the parsed tree. |
2806 """ | 3340 """ |
2807 revs = None | 3341 revs = None |
2808 if opts[r'rev']: | 3342 if opts[r'rev']: |
2809 if repo is None: | 3343 if repo is None: |
2810 raise error.RepoError(_('there is no Mercurial repository here ' | 3344 raise error.RepoError( |
2811 '(.hg not found)')) | 3345 _('there is no Mercurial repository here ' '(.hg not found)') |
3346 ) | |
2812 revs = scmutil.revrange(repo, opts[r'rev']) | 3347 revs = scmutil.revrange(repo, opts[r'rev']) |
2813 | 3348 |
2814 props = {} | 3349 props = {} |
2815 for d in opts[r'define']: | 3350 for d in opts[r'define']: |
2816 try: | 3351 try: |
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]] |
2960 res2 = repo.debugwireargs(*vals, **args) | 3525 res2 = repo.debugwireargs(*vals, **args) |
2961 ui.write("%s\n" % res1) | 3526 ui.write("%s\n" % res1) |
2962 if res1 != res2: | 3527 if res1 != res2: |
2963 ui.warn("%s\n" % res2) | 3528 ui.warn("%s\n" % res2) |
2964 | 3529 |
3530 | |
2965 def _parsewirelangblocks(fh): | 3531 def _parsewirelangblocks(fh): |
2966 activeaction = None | 3532 activeaction = None |
2967 blocklines = [] | 3533 blocklines = [] |
2968 lastindent = 0 | 3534 lastindent = 0 |
2969 | 3535 |
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. |
3198 | 3772 |
3199 if opts['localssh'] and not repo: | 3773 if opts['localssh'] and not repo: |
3200 raise error.Abort(_('--localssh requires a repository')) | 3774 raise error.Abort(_('--localssh requires a repository')) |
3201 | 3775 |
3202 if opts['peer'] and opts['peer'] not in ('raw', 'http2', 'ssh1', 'ssh2'): | 3776 if opts['peer'] and opts['peer'] not in ('raw', 'http2', 'ssh1', 'ssh2'): |
3203 raise error.Abort(_('invalid value for --peer'), | 3777 raise error.Abort( |
3204 hint=_('valid values are "raw", "ssh1", and "ssh2"')) | 3778 _('invalid value for --peer'), |
3779 hint=_('valid values are "raw", "ssh1", and "ssh2"'), | |
3780 ) | |
3205 | 3781 |
3206 if path and opts['localssh']: | 3782 if path and opts['localssh']: |
3207 raise error.Abort(_('cannot specify --localssh with an explicit ' | 3783 raise error.Abort( |
3208 'path')) | 3784 _('cannot specify --localssh with an explicit ' 'path') |
3785 ) | |
3209 | 3786 |
3210 if ui.interactive(): | 3787 if ui.interactive(): |
3211 ui.write(_('(waiting for commands on stdin)\n')) | 3788 ui.write(_('(waiting for commands on stdin)\n')) |
3212 | 3789 |
3213 blocks = list(_parsewirelangblocks(ui.fin)) | 3790 blocks = list(_parsewirelangblocks(ui.fin)) |
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. |
3278 r'useragent': b'Mercurial debugwireproto', | 3886 r'useragent': b'Mercurial debugwireproto', |
3279 } | 3887 } |
3280 | 3888 |
3281 # Turn pipes/sockets into observers so we can log I/O. | 3889 # Turn pipes/sockets into observers so we can log I/O. |
3282 if ui.verbose: | 3890 if ui.verbose: |
3283 openerargs.update({ | 3891 openerargs.update( |
3284 r'loggingfh': ui, | 3892 { |
3285 r'loggingname': b's', | 3893 r'loggingfh': ui, |
3286 r'loggingopts': { | 3894 r'loggingname': b's', |
3287 r'logdata': True, | 3895 r'loggingopts': {r'logdata': True, r'logdataapis': False,}, |
3288 r'logdataapis': False, | 3896 } |
3289 }, | 3897 ) |
3290 }) | |
3291 | 3898 |
3292 if ui.debugflag: | 3899 if ui.debugflag: |
3293 openerargs[r'loggingopts'][r'logdataapis'] = True | 3900 openerargs[r'loggingopts'][r'logdataapis'] = True |
3294 | 3901 |
3295 # Don't send default headers when in raw mode. This allows us to | 3902 # Don't send default headers when in raw mode. This allows us to |
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: |
3353 if not stdin: | 3968 if not stdin: |
3354 raise error.Abort(_('cannot call flush on this peer')) | 3969 raise error.Abort(_('cannot call flush on this peer')) |
3355 stdin.flush() | 3970 stdin.flush() |
3356 elif action.startswith('command'): | 3971 elif action.startswith('command'): |
3357 if not peer: | 3972 if not peer: |
3358 raise error.Abort(_('cannot send commands unless peer instance ' | 3973 raise error.Abort( |
3359 'is available')) | 3974 _( |
3975 'cannot send commands unless peer instance ' | |
3976 'is available' | |
3977 ) | |
3978 ) | |
3360 | 3979 |
3361 command = action.split(' ', 1)[1] | 3980 command = action.split(' ', 1)[1] |
3362 | 3981 |
3363 args = {} | 3982 args = {} |
3364 for line in lines: | 3983 for line in lines: |
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 = [] |
3447 if line.startswith(b'BODYFILE '): | 4079 if line.startswith(b'BODYFILE '): |
3448 with open(line.split(b' ', 1), 'rb') as fh: | 4080 with open(line.split(b' ', 1), 'rb') as fh: |
3449 body = fh.read() | 4081 body = fh.read() |
3450 elif line.startswith(b'frame '): | 4082 elif line.startswith(b'frame '): |
3451 frame = wireprotoframing.makeframefromhumanstring( | 4083 frame = wireprotoframing.makeframefromhumanstring( |
3452 line[len(b'frame '):]) | 4084 line[len(b'frame ') :] |
4085 ) | |
3453 | 4086 |
3454 frames.append(frame) | 4087 frames.append(frame) |
3455 else: | 4088 else: |
3456 raise error.Abort(_('unknown argument to httprequest: %s') % | 4089 raise error.Abort( |
3457 line) | 4090 _('unknown argument to httprequest: %s') % line |
4091 ) | |
3458 | 4092 |
3459 url = path + httppath | 4093 url = path + httppath |
3460 | 4094 |
3461 if frames: | 4095 if frames: |
3462 body = b''.join(bytes(f) for f in frames) | 4096 body = b''.join(bytes(f) for f in frames) |
3476 getattr(e, 'read', lambda: None)() | 4110 getattr(e, 'read', lambda: None)() |
3477 continue | 4111 continue |
3478 | 4112 |
3479 ct = res.headers.get(r'Content-Type') | 4113 ct = res.headers.get(r'Content-Type') |
3480 if ct == r'application/mercurial-cbor': | 4114 if ct == r'application/mercurial-cbor': |
3481 ui.write(_('cbor> %s\n') % | 4115 ui.write( |
3482 stringutil.pprint(cborutil.decodeall(body), | 4116 _('cbor> %s\n') |
3483 bprefix=True, | 4117 % stringutil.pprint( |
3484 indent=2)) | 4118 cborutil.decodeall(body), bprefix=True, indent=2 |
4119 ) | |
4120 ) | |
3485 | 4121 |
3486 elif action == 'close': | 4122 elif action == 'close': |
3487 peer.close() | 4123 peer.close() |
3488 elif action == 'readavailable': | 4124 elif action == 'readavailable': |
3489 if not stdout or not stderr: | 4125 if not stdout or not stderr: |