mercurial/debugcommands.py
changeset 43506 9f70512ae2cf
parent 43503 313e3a279828
child 43633 0b7733719d21
equal deleted inserted replaced
43505:47fac1692ede 43506:9f70512ae2cf
   391 def _debugbundle2(ui, gen, all=None, **opts):
   391 def _debugbundle2(ui, gen, all=None, **opts):
   392     """lists the contents of a bundle2"""
   392     """lists the contents of a bundle2"""
   393     if not isinstance(gen, bundle2.unbundle20):
   393     if not isinstance(gen, bundle2.unbundle20):
   394         raise error.Abort(_(b'not a bundle2 file'))
   394         raise error.Abort(_(b'not a bundle2 file'))
   395     ui.write((b'Stream params: %s\n' % _quasirepr(gen.params)))
   395     ui.write((b'Stream params: %s\n' % _quasirepr(gen.params)))
   396     parttypes = opts.get(r'part_type', [])
   396     parttypes = opts.get('part_type', [])
   397     for part in gen.iterparts():
   397     for part in gen.iterparts():
   398         if parttypes and part.type not in parttypes:
   398         if parttypes and part.type not in parttypes:
   399             continue
   399             continue
   400         msg = b'%s -- %s (mandatory: %r)\n'
   400         msg = b'%s -- %s (mandatory: %r)\n'
   401         ui.write((msg % (part.type, _quasirepr(part.params), part.mandatory)))
   401         ui.write((msg % (part.type, _quasirepr(part.params), part.mandatory)))
   490     b'hg debugcolor',
   490     b'hg debugcolor',
   491 )
   491 )
   492 def debugcolor(ui, repo, **opts):
   492 def debugcolor(ui, repo, **opts):
   493     """show available color, effects or style"""
   493     """show available color, effects or style"""
   494     ui.writenoi18n(b'color mode: %s\n' % stringutil.pprint(ui._colormode))
   494     ui.writenoi18n(b'color mode: %s\n' % stringutil.pprint(ui._colormode))
   495     if opts.get(r'style'):
   495     if opts.get('style'):
   496         return _debugdisplaystyle(ui)
   496         return _debugdisplaystyle(ui)
   497     else:
   497     else:
   498         return _debugdisplaycolor(ui)
   498         return _debugdisplaycolor(ui)
   499 
   499 
   500 
   500 
   571     If you pass a revlog index, the revlog's DAG is emitted. If you list
   571     If you pass a revlog index, the revlog's DAG is emitted. If you list
   572     revision numbers, they get labeled in the output as rN.
   572     revision numbers, they get labeled in the output as rN.
   573 
   573 
   574     Otherwise, the changelog DAG of the current repo is emitted.
   574     Otherwise, the changelog DAG of the current repo is emitted.
   575     """
   575     """
   576     spaces = opts.get(r'spaces')
   576     spaces = opts.get('spaces')
   577     dots = opts.get(r'dots')
   577     dots = opts.get('dots')
   578     if file_:
   578     if file_:
   579         rlog = revlog.revlog(vfsmod.vfs(encoding.getcwd(), audit=False), file_)
   579         rlog = revlog.revlog(vfsmod.vfs(encoding.getcwd(), audit=False), file_)
   580         revs = set((int(r) for r in revs))
   580         revs = set((int(r) for r in revs))
   581 
   581 
   582         def events():
   582         def events():
   585                 if r in revs:
   585                 if r in revs:
   586                     yield b'l', (r, b"r%i" % r)
   586                     yield b'l', (r, b"r%i" % r)
   587 
   587 
   588     elif repo:
   588     elif repo:
   589         cl = repo.changelog
   589         cl = repo.changelog
   590         tags = opts.get(r'tags')
   590         tags = opts.get('tags')
   591         branches = opts.get(r'branches')
   591         branches = opts.get('branches')
   592         if tags:
   592         if tags:
   593             labels = {}
   593             labels = {}
   594             for l, n in repo.tags().items():
   594             for l, n in repo.tags().items():
   595                 labels.setdefault(cl.rev(n), []).append(l)
   595                 labels.setdefault(cl.rev(n), []).append(l)
   596 
   596 
   859     _(b'[OPTION]...'),
   859     _(b'[OPTION]...'),
   860 )
   860 )
   861 def debugstate(ui, repo, **opts):
   861 def debugstate(ui, repo, **opts):
   862     """show the contents of the current dirstate"""
   862     """show the contents of the current dirstate"""
   863 
   863 
   864     nodates = not opts[r'dates']
   864     nodates = not opts['dates']
   865     if opts.get(r'nodates') is not None:
   865     if opts.get('nodates') is not None:
   866         nodates = True
   866         nodates = True
   867     datesort = opts.get(r'datesort')
   867     datesort = opts.get('datesort')
   868 
   868 
   869     if datesort:
   869     if datesort:
   870         keyfunc = lambda x: (x[1][3], x[0])  # sort by mtime, then by filename
   870         keyfunc = lambda x: (x[1][3], x[0])  # sort by mtime, then by filename
   871     else:
   871     else:
   872         keyfunc = None  # sort by filename
   872         keyfunc = None  # sort by filename
  1296     repo = hg.peer(ui, opts, repopath)
  1296     repo = hg.peer(ui, opts, repopath)
  1297     if not repo.capable(b'getbundle'):
  1297     if not repo.capable(b'getbundle'):
  1298         raise error.Abort(b"getbundle() not supported by target repository")
  1298         raise error.Abort(b"getbundle() not supported by target repository")
  1299     args = {}
  1299     args = {}
  1300     if common:
  1300     if common:
  1301         args[r'common'] = [bin(s) for s in common]
  1301         args['common'] = [bin(s) for s in common]
  1302     if head:
  1302     if head:
  1303         args[r'heads'] = [bin(s) for s in head]
  1303         args['heads'] = [bin(s) for s in head]
  1304     # TODO: get desired bundlecaps from command line.
  1304     # TODO: get desired bundlecaps from command line.
  1305     args[r'bundlecaps'] = None
  1305     args['bundlecaps'] = None
  1306     bundle = repo.getbundle(b'debug', **args)
  1306     bundle = repo.getbundle(b'debug', **args)
  1307 
  1307 
  1308     bundletype = opts.get(b'type', b'bzip2').lower()
  1308     bundletype = opts.get(b'type', b'bzip2').lower()
  1309     btypes = {
  1309     btypes = {
  1310         b'none': b'HG10UN',
  1310         b'none': b'HG10UN',
  1773 
  1773 
  1774     Returns 0 if no locks are held.
  1774     Returns 0 if no locks are held.
  1775 
  1775 
  1776     """
  1776     """
  1777 
  1777 
  1778     if opts.get(r'force_lock'):
  1778     if opts.get('force_lock'):
  1779         repo.svfs.unlink(b'lock')
  1779         repo.svfs.unlink(b'lock')
  1780     if opts.get(r'force_wlock'):
  1780     if opts.get('force_wlock'):
  1781         repo.vfs.unlink(b'wlock')
  1781         repo.vfs.unlink(b'wlock')
  1782     if opts.get(r'force_lock') or opts.get(r'force_wlock'):
  1782     if opts.get('force_lock') or opts.get('force_wlock'):
  1783         return 0
  1783         return 0
  1784 
  1784 
  1785     locks = []
  1785     locks = []
  1786     try:
  1786     try:
  1787         if opts.get(r'set_wlock'):
  1787         if opts.get('set_wlock'):
  1788             try:
  1788             try:
  1789                 locks.append(repo.wlock(False))
  1789                 locks.append(repo.wlock(False))
  1790             except error.LockHeld:
  1790             except error.LockHeld:
  1791                 raise error.Abort(_(b'wlock is already held'))
  1791                 raise error.Abort(_(b'wlock is already held'))
  1792         if opts.get(r'set_lock'):
  1792         if opts.get('set_lock'):
  1793             try:
  1793             try:
  1794                 locks.append(repo.lock(False))
  1794                 locks.append(repo.lock(False))
  1795             except error.LockHeld:
  1795             except error.LockHeld:
  1796                 raise error.Abort(_(b'lock is already held'))
  1796                 raise error.Abort(_(b'lock is already held'))
  1797         if len(locks):
  1797         if len(locks):
  1869                 b"Current revlog implementation doesn't appear to have a "
  1869                 b"Current revlog implementation doesn't appear to have a "
  1870                 b"manifest fulltext cache\n"
  1870                 b"manifest fulltext cache\n"
  1871             )
  1871             )
  1872             raise error.Abort(msg)
  1872             raise error.Abort(msg)
  1873 
  1873 
  1874     if opts.get(r'clear'):
  1874     if opts.get('clear'):
  1875         with repo.wlock():
  1875         with repo.wlock():
  1876             cache = getcache()
  1876             cache = getcache()
  1877             cache.clear(clear_persisted_data=True)
  1877             cache.clear(clear_persisted_data=True)
  1878             return
  1878             return
  1879 
  1879 
  2263         spec = spec[len(rootdir) :]
  2263         spec = spec[len(rootdir) :]
  2264         fixpaths = pycompat.ossep != b'/'
  2264         fixpaths = pycompat.ossep != b'/'
  2265         if fixpaths:
  2265         if fixpaths:
  2266             spec = spec.replace(pycompat.ossep, b'/')
  2266             spec = spec.replace(pycompat.ossep, b'/')
  2267         speclen = len(spec)
  2267         speclen = len(spec)
  2268         fullpaths = opts[r'full']
  2268         fullpaths = opts['full']
  2269         files, dirs = set(), set()
  2269         files, dirs = set(), set()
  2270         adddir, addfile = dirs.add, files.add
  2270         adddir, addfile = dirs.add, files.add
  2271         for f, st in pycompat.iteritems(dirstate):
  2271         for f, st in pycompat.iteritems(dirstate):
  2272             if f.startswith(spec) and st[0] in acceptable:
  2272             if f.startswith(spec) and st[0] in acceptable:
  2273                 if fixpaths:
  2273                 if fixpaths:
  2281                 else:
  2281                 else:
  2282                     addfile(f)
  2282                     addfile(f)
  2283         return files, dirs
  2283         return files, dirs
  2284 
  2284 
  2285     acceptable = b''
  2285     acceptable = b''
  2286     if opts[r'normal']:
  2286     if opts['normal']:
  2287         acceptable += b'nm'
  2287         acceptable += b'nm'
  2288     if opts[r'added']:
  2288     if opts['added']:
  2289         acceptable += b'a'
  2289         acceptable += b'a'
  2290     if opts[r'removed']:
  2290     if opts['removed']:
  2291         acceptable += b'r'
  2291         acceptable += b'r'
  2292     cwd = repo.getcwd()
  2292     cwd = repo.getcwd()
  2293     if not specs:
  2293     if not specs:
  2294         specs = [b'.']
  2294         specs = [b'.']
  2295 
  2295 
  2524     ctx = scmutil.revsingle(repo, rev)
  2524     ctx = scmutil.revsingle(repo, rev)
  2525     with repo.wlock():
  2525     with repo.wlock():
  2526         dirstate = repo.dirstate
  2526         dirstate = repo.dirstate
  2527         changedfiles = None
  2527         changedfiles = None
  2528         # See command doc for what minimal does.
  2528         # See command doc for what minimal does.
  2529         if opts.get(r'minimal'):
  2529         if opts.get('minimal'):
  2530             manifestfiles = set(ctx.manifest().keys())
  2530             manifestfiles = set(ctx.manifest().keys())
  2531             dirstatefiles = set(dirstate)
  2531             dirstatefiles = set(dirstate)
  2532             manifestonly = manifestfiles - dirstatefiles
  2532             manifestonly = manifestfiles - dirstatefiles
  2533             dsonly = dirstatefiles - manifestfiles
  2533             dsonly = dirstatefiles - manifestfiles
  2534             dsnotadded = set(f for f in dsonly if dirstate[f] != b'a')
  2534             dsnotadded = set(f for f in dsonly if dirstate[f] != b'a')
  3145             return 0
  3145             return 0
  3146         ui.writenoi18n(b'--- analyzed\n', label=b'diff.file_a')
  3146         ui.writenoi18n(b'--- analyzed\n', label=b'diff.file_a')
  3147         ui.writenoi18n(b'+++ optimized\n', label=b'diff.file_b')
  3147         ui.writenoi18n(b'+++ optimized\n', label=b'diff.file_b')
  3148         sm = difflib.SequenceMatcher(None, arevs, brevs)
  3148         sm = difflib.SequenceMatcher(None, arevs, brevs)
  3149         for tag, alo, ahi, blo, bhi in sm.get_opcodes():
  3149         for tag, alo, ahi, blo, bhi in sm.get_opcodes():
  3150             if tag in (r'delete', r'replace'):
  3150             if tag in ('delete', 'replace'):
  3151                 for c in arevs[alo:ahi]:
  3151                 for c in arevs[alo:ahi]:
  3152                     ui.write(b'-%d\n' % c, label=b'diff.deleted')
  3152                     ui.write(b'-%d\n' % c, label=b'diff.deleted')
  3153             if tag in (r'insert', r'replace'):
  3153             if tag in ('insert', 'replace'):
  3154                 for c in brevs[blo:bhi]:
  3154                 for c in brevs[blo:bhi]:
  3155                     ui.write(b'+%d\n' % c, label=b'diff.inserted')
  3155                     ui.write(b'+%d\n' % c, label=b'diff.inserted')
  3156             if tag == r'equal':
  3156             if tag == 'equal':
  3157                 for c in arevs[alo:ahi]:
  3157                 for c in arevs[alo:ahi]:
  3158                     ui.write(b' %d\n' % c)
  3158                     ui.write(b' %d\n' % c)
  3159         return 1
  3159         return 1
  3160 
  3160 
  3161     func = revset.makematcher(tree)
  3161     func = revset.makematcher(tree)
  3200         raise error.Abort(_(b'cannot use both --logiofd and --logiofile'))
  3200         raise error.Abort(_(b'cannot use both --logiofd and --logiofile'))
  3201 
  3201 
  3202     if opts[b'logiofd']:
  3202     if opts[b'logiofd']:
  3203         # Line buffered because output is line based.
  3203         # Line buffered because output is line based.
  3204         try:
  3204         try:
  3205             logfh = os.fdopen(int(opts[b'logiofd']), r'ab', 1)
  3205             logfh = os.fdopen(int(opts[b'logiofd']), 'ab', 1)
  3206         except OSError as e:
  3206         except OSError as e:
  3207             if e.errno != errno.ESPIPE:
  3207             if e.errno != errno.ESPIPE:
  3208                 raise
  3208                 raise
  3209             # can't seek a pipe, so `ab` mode fails on py3
  3209             # can't seek a pipe, so `ab` mode fails on py3
  3210             logfh = os.fdopen(int(opts[b'logiofd']), r'wb', 1)
  3210             logfh = os.fdopen(int(opts[b'logiofd']), 'wb', 1)
  3211     elif opts[b'logiofile']:
  3211     elif opts[b'logiofile']:
  3212         logfh = open(opts[b'logiofile'], b'ab', 1)
  3212         logfh = open(opts[b'logiofile'], b'ab', 1)
  3213 
  3213 
  3214     s = wireprotoserver.sshserver(ui, repo, logfh=logfh)
  3214     s = wireprotoserver.sshserver(ui, repo, logfh=logfh)
  3215     s.serve_forever()
  3215     s.serve_forever()
  3389     node2str = short
  3389     node2str = short
  3390     for rev in scmutil.revrange(repo, revs):
  3390     for rev in scmutil.revrange(repo, revs):
  3391         ctx = repo[rev]
  3391         ctx = repo[rev]
  3392         ui.write(b'%s\n' % ctx2str(ctx))
  3392         ui.write(b'%s\n' % ctx2str(ctx))
  3393         for succsset in obsutil.successorssets(
  3393         for succsset in obsutil.successorssets(
  3394             repo, ctx.node(), closest=opts[r'closest'], cache=cache
  3394             repo, ctx.node(), closest=opts['closest'], cache=cache
  3395         ):
  3395         ):
  3396             if succsset:
  3396             if succsset:
  3397                 ui.write(b'    ')
  3397                 ui.write(b'    ')
  3398                 ui.write(node2str(succsset[0]))
  3398                 ui.write(node2str(succsset[0]))
  3399                 for node in succsset[1:]:
  3399                 for node in succsset[1:]:
  3419     template.
  3419     template.
  3420 
  3420 
  3421     Use --verbose to print the parsed tree.
  3421     Use --verbose to print the parsed tree.
  3422     """
  3422     """
  3423     revs = None
  3423     revs = None
  3424     if opts[r'rev']:
  3424     if opts['rev']:
  3425         if repo is None:
  3425         if repo is None:
  3426             raise error.RepoError(
  3426             raise error.RepoError(
  3427                 _(b'there is no Mercurial repository here (.hg not found)')
  3427                 _(b'there is no Mercurial repository here (.hg not found)')
  3428             )
  3428             )
  3429         revs = scmutil.revrange(repo, opts[r'rev'])
  3429         revs = scmutil.revrange(repo, opts['rev'])
  3430 
  3430 
  3431     props = {}
  3431     props = {}
  3432     for d in opts[r'define']:
  3432     for d in opts['define']:
  3433         try:
  3433         try:
  3434             k, v = (e.strip() for e in d.split(b'=', 1))
  3434             k, v = (e.strip() for e in d.split(b'=', 1))
  3435             if not k or k == b'ui':
  3435             if not k or k == b'ui':
  3436                 raise ValueError
  3436                 raise ValueError
  3437             props[k] = v
  3437             props[k] = v
  3983         if u.scheme != b'http':
  3983         if u.scheme != b'http':
  3984             raise error.Abort(_(b'only http:// paths are currently supported'))
  3984             raise error.Abort(_(b'only http:// paths are currently supported'))
  3985 
  3985 
  3986         url, authinfo = u.authinfo()
  3986         url, authinfo = u.authinfo()
  3987         openerargs = {
  3987         openerargs = {
  3988             r'useragent': b'Mercurial debugwireproto',
  3988             'useragent': b'Mercurial debugwireproto',
  3989         }
  3989         }
  3990 
  3990 
  3991         # Turn pipes/sockets into observers so we can log I/O.
  3991         # Turn pipes/sockets into observers so we can log I/O.
  3992         if ui.verbose:
  3992         if ui.verbose:
  3993             openerargs.update(
  3993             openerargs.update(
  3994                 {
  3994                 {
  3995                     r'loggingfh': ui,
  3995                     'loggingfh': ui,
  3996                     r'loggingname': b's',
  3996                     'loggingname': b's',
  3997                     r'loggingopts': {r'logdata': True, r'logdataapis': False,},
  3997                     'loggingopts': {'logdata': True, 'logdataapis': False,},
  3998                 }
  3998                 }
  3999             )
  3999             )
  4000 
  4000 
  4001         if ui.debugflag:
  4001         if ui.debugflag:
  4002             openerargs[r'loggingopts'][r'logdataapis'] = True
  4002             openerargs['loggingopts']['logdataapis'] = True
  4003 
  4003 
  4004         # Don't send default headers when in raw mode. This allows us to
  4004         # Don't send default headers when in raw mode. This allows us to
  4005         # bypass most of the behavior of our URL handling code so we can
  4005         # bypass most of the behavior of our URL handling code so we can
  4006         # have near complete control over what's sent on the wire.
  4006         # have near complete control over what's sent on the wire.
  4007         if opts[b'peer'] == b'raw':
  4007         if opts[b'peer'] == b'raw':
  4008             openerargs[r'sendaccept'] = False
  4008             openerargs['sendaccept'] = False
  4009 
  4009 
  4010         opener = urlmod.opener(ui, authinfo, **openerargs)
  4010         opener = urlmod.opener(ui, authinfo, **openerargs)
  4011 
  4011 
  4012         if opts[b'peer'] == b'http2':
  4012         if opts[b'peer'] == b'http2':
  4013             ui.write(_(b'creating http peer for wire protocol version 2\n'))
  4013             ui.write(_(b'creating http peer for wire protocol version 2\n'))
  4103                 continue
  4103                 continue
  4104 
  4104 
  4105             ui.status(_(b'sending %s command\n') % command)
  4105             ui.status(_(b'sending %s command\n') % command)
  4106 
  4106 
  4107             if b'PUSHFILE' in args:
  4107             if b'PUSHFILE' in args:
  4108                 with open(args[b'PUSHFILE'], r'rb') as fh:
  4108                 with open(args[b'PUSHFILE'], 'rb') as fh:
  4109                     del args[b'PUSHFILE']
  4109                     del args[b'PUSHFILE']
  4110                     res, output = peer._callpush(
  4110                     res, output = peer._callpush(
  4111                         command, fh, **pycompat.strkwargs(args)
  4111                         command, fh, **pycompat.strkwargs(args)
  4112                     )
  4112                     )
  4113                     ui.status(_(b'result: %s\n') % stringutil.escapestr(res))
  4113                     ui.status(_(b'result: %s\n') % stringutil.escapestr(res))
  4211             except util.urlerr.urlerror as e:
  4211             except util.urlerr.urlerror as e:
  4212                 # read() method must be called, but only exists in Python 2
  4212                 # read() method must be called, but only exists in Python 2
  4213                 getattr(e, 'read', lambda: None)()
  4213                 getattr(e, 'read', lambda: None)()
  4214                 continue
  4214                 continue
  4215 
  4215 
  4216             ct = res.headers.get(r'Content-Type')
  4216             ct = res.headers.get('Content-Type')
  4217             if ct == r'application/mercurial-cbor':
  4217             if ct == 'application/mercurial-cbor':
  4218                 ui.write(
  4218                 ui.write(
  4219                     _(b'cbor> %s\n')
  4219                     _(b'cbor> %s\n')
  4220                     % stringutil.pprint(
  4220                     % stringutil.pprint(
  4221                         cborutil.decodeall(body), bprefix=True, indent=2
  4221                         cborutil.decodeall(body), bprefix=True, indent=2
  4222                     )
  4222                     )