mercurial/commands.py
changeset 43077 687b865b95ad
parent 43076 2372284d9457
child 43085 eef9a2d67051
equal deleted inserted replaced
43076:2372284d9457 43077:687b865b95ad
    79 
    79 
    80 # common command options
    80 # common command options
    81 
    81 
    82 globalopts = [
    82 globalopts = [
    83     (
    83     (
    84         'R',
    84         b'R',
    85         'repository',
    85         b'repository',
    86         '',
    86         b'',
    87         _('repository root directory or name of overlay bundle file'),
    87         _(b'repository root directory or name of overlay bundle file'),
    88         _('REPO'),
    88         _(b'REPO'),
    89     ),
    89     ),
    90     ('', 'cwd', '', _('change working directory'), _('DIR')),
    90     (b'', b'cwd', b'', _(b'change working directory'), _(b'DIR')),
    91     (
    91     (
    92         'y',
    92         b'y',
    93         'noninteractive',
    93         b'noninteractive',
    94         None,
    94         None,
    95         _('do not prompt, automatically pick the first choice for all prompts'),
    95         _(
       
    96             b'do not prompt, automatically pick the first choice for all prompts'
       
    97         ),
    96     ),
    98     ),
    97     ('q', 'quiet', None, _('suppress output')),
    99     (b'q', b'quiet', None, _(b'suppress output')),
    98     ('v', 'verbose', None, _('enable additional output')),
   100     (b'v', b'verbose', None, _(b'enable additional output')),
    99     (
   101     (
   100         '',
   102         b'',
   101         'color',
   103         b'color',
   102         '',
   104         b'',
   103         # i18n: 'always', 'auto', 'never', and 'debug' are keywords
   105         # i18n: 'always', 'auto', 'never', and 'debug' are keywords
   104         # and should not be translated
   106         # and should not be translated
   105         _("when to colorize (boolean, always, auto, never, or debug)"),
   107         _(b"when to colorize (boolean, always, auto, never, or debug)"),
   106         _('TYPE'),
   108         _(b'TYPE'),
   107     ),
   109     ),
   108     (
   110     (
   109         '',
   111         b'',
   110         'config',
   112         b'config',
   111         [],
   113         [],
   112         _('set/override config option (use \'section.name=value\')'),
   114         _(b'set/override config option (use \'section.name=value\')'),
   113         _('CONFIG'),
   115         _(b'CONFIG'),
   114     ),
   116     ),
   115     ('', 'debug', None, _('enable debugging output')),
   117     (b'', b'debug', None, _(b'enable debugging output')),
   116     ('', 'debugger', None, _('start debugger')),
   118     (b'', b'debugger', None, _(b'start debugger')),
   117     (
   119     (
   118         '',
   120         b'',
   119         'encoding',
   121         b'encoding',
   120         encoding.encoding,
   122         encoding.encoding,
   121         _('set the charset encoding'),
   123         _(b'set the charset encoding'),
   122         _('ENCODE'),
   124         _(b'ENCODE'),
   123     ),
   125     ),
   124     (
   126     (
   125         '',
   127         b'',
   126         'encodingmode',
   128         b'encodingmode',
   127         encoding.encodingmode,
   129         encoding.encodingmode,
   128         _('set the charset encoding mode'),
   130         _(b'set the charset encoding mode'),
   129         _('MODE'),
   131         _(b'MODE'),
   130     ),
   132     ),
   131     ('', 'traceback', None, _('always print a traceback on exception')),
   133     (b'', b'traceback', None, _(b'always print a traceback on exception')),
   132     ('', 'time', None, _('time how long the command takes')),
   134     (b'', b'time', None, _(b'time how long the command takes')),
   133     ('', 'profile', None, _('print command execution profile')),
   135     (b'', b'profile', None, _(b'print command execution profile')),
   134     ('', 'version', None, _('output version information and exit')),
   136     (b'', b'version', None, _(b'output version information and exit')),
   135     ('h', 'help', None, _('display help and exit')),
   137     (b'h', b'help', None, _(b'display help and exit')),
   136     ('', 'hidden', False, _('consider hidden changesets')),
   138     (b'', b'hidden', False, _(b'consider hidden changesets')),
   137     (
   139     (
   138         '',
   140         b'',
   139         'pager',
   141         b'pager',
   140         'auto',
   142         b'auto',
   141         _("when to paginate (boolean, always, auto, or never)"),
   143         _(b"when to paginate (boolean, always, auto, or never)"),
   142         _('TYPE'),
   144         _(b'TYPE'),
   143     ),
   145     ),
   144 ]
   146 ]
   145 
   147 
   146 dryrunopts = cmdutil.dryrunopts
   148 dryrunopts = cmdutil.dryrunopts
   147 remoteopts = cmdutil.remoteopts
   149 remoteopts = cmdutil.remoteopts
   162 
   164 
   163 # Commands start here, listed alphabetically
   165 # Commands start here, listed alphabetically
   164 
   166 
   165 
   167 
   166 @command(
   168 @command(
   167     'abort',
   169     b'abort',
   168     dryrunopts,
   170     dryrunopts,
   169     helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
   171     helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
   170     helpbasic=True,
   172     helpbasic=True,
   171 )
   173 )
   172 def abort(ui, repo, **opts):
   174 def abort(ui, repo, **opts):
   178     use --dry-run/-n to dry run the command.
   180     use --dry-run/-n to dry run the command.
   179     """
   181     """
   180     dryrun = opts.get(r'dry_run')
   182     dryrun = opts.get(r'dry_run')
   181     abortstate = cmdutil.getunfinishedstate(repo)
   183     abortstate = cmdutil.getunfinishedstate(repo)
   182     if not abortstate:
   184     if not abortstate:
   183         raise error.Abort(_('no operation in progress'))
   185         raise error.Abort(_(b'no operation in progress'))
   184     if not abortstate.abortfunc:
   186     if not abortstate.abortfunc:
   185         raise error.Abort(
   187         raise error.Abort(
   186             (
   188             (
   187                 _("%s in progress but does not support 'hg abort'")
   189                 _(b"%s in progress but does not support 'hg abort'")
   188                 % (abortstate._opname)
   190                 % (abortstate._opname)
   189             ),
   191             ),
   190             hint=abortstate.hint(),
   192             hint=abortstate.hint(),
   191         )
   193         )
   192     if dryrun:
   194     if dryrun:
   193         ui.status(_('%s in progress, will be aborted\n') % (abortstate._opname))
   195         ui.status(
       
   196             _(b'%s in progress, will be aborted\n') % (abortstate._opname)
       
   197         )
   194         return
   198         return
   195     return abortstate.abortfunc(ui, repo)
   199     return abortstate.abortfunc(ui, repo)
   196 
   200 
   197 
   201 
   198 @command(
   202 @command(
   199     'add',
   203     b'add',
   200     walkopts + subrepoopts + dryrunopts,
   204     walkopts + subrepoopts + dryrunopts,
   201     _('[OPTION]... [FILE]...'),
   205     _(b'[OPTION]... [FILE]...'),
   202     helpcategory=command.CATEGORY_WORKING_DIRECTORY,
   206     helpcategory=command.CATEGORY_WORKING_DIRECTORY,
   203     helpbasic=True,
   207     helpbasic=True,
   204     inferrepo=True,
   208     inferrepo=True,
   205 )
   209 )
   206 def add(ui, repo, *pats, **opts):
   210 def add(ui, repo, *pats, **opts):
   246     Returns 0 if all files are successfully added.
   250     Returns 0 if all files are successfully added.
   247     """
   251     """
   248 
   252 
   249     m = scmutil.match(repo[None], pats, pycompat.byteskwargs(opts))
   253     m = scmutil.match(repo[None], pats, pycompat.byteskwargs(opts))
   250     uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
   254     uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
   251     rejected = cmdutil.add(ui, repo, m, "", uipathfn, False, **opts)
   255     rejected = cmdutil.add(ui, repo, m, b"", uipathfn, False, **opts)
   252     return rejected and 1 or 0
   256     return rejected and 1 or 0
   253 
   257 
   254 
   258 
   255 @command(
   259 @command(
   256     'addremove',
   260     b'addremove',
   257     similarityopts + subrepoopts + walkopts + dryrunopts,
   261     similarityopts + subrepoopts + walkopts + dryrunopts,
   258     _('[OPTION]... [FILE]...'),
   262     _(b'[OPTION]... [FILE]...'),
   259     helpcategory=command.CATEGORY_WORKING_DIRECTORY,
   263     helpcategory=command.CATEGORY_WORKING_DIRECTORY,
   260     inferrepo=True,
   264     inferrepo=True,
   261 )
   265 )
   262 def addremove(ui, repo, *pats, **opts):
   266 def addremove(ui, repo, *pats, **opts):
   263     """add all new files, delete all missing files
   267     """add all new files, delete all missing files
   320              R foobar.c
   324              R foobar.c
   321 
   325 
   322     Returns 0 if all files are successfully added.
   326     Returns 0 if all files are successfully added.
   323     """
   327     """
   324     opts = pycompat.byteskwargs(opts)
   328     opts = pycompat.byteskwargs(opts)
   325     if not opts.get('similarity'):
   329     if not opts.get(b'similarity'):
   326         opts['similarity'] = '100'
   330         opts[b'similarity'] = b'100'
   327     matcher = scmutil.match(repo[None], pats, opts)
   331     matcher = scmutil.match(repo[None], pats, opts)
   328     relative = scmutil.anypats(pats, opts)
   332     relative = scmutil.anypats(pats, opts)
   329     uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=relative)
   333     uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=relative)
   330     return scmutil.addremove(repo, matcher, "", uipathfn, opts)
   334     return scmutil.addremove(repo, matcher, b"", uipathfn, opts)
   331 
   335 
   332 
   336 
   333 @command(
   337 @command(
   334     'annotate|blame',
   338     b'annotate|blame',
   335     [
   339     [
   336         ('r', 'rev', '', _('annotate the specified revision'), _('REV')),
   340         (b'r', b'rev', b'', _(b'annotate the specified revision'), _(b'REV')),
   337         (
   341         (
   338             '',
   342             b'',
   339             'follow',
   343             b'follow',
   340             None,
   344             None,
   341             _('follow copies/renames and list the filename (DEPRECATED)'),
   345             _(b'follow copies/renames and list the filename (DEPRECATED)'),
   342         ),
   346         ),
   343         ('', 'no-follow', None, _("don't follow copies and renames")),
   347         (b'', b'no-follow', None, _(b"don't follow copies and renames")),
   344         ('a', 'text', None, _('treat all files as text')),
   348         (b'a', b'text', None, _(b'treat all files as text')),
   345         ('u', 'user', None, _('list the author (long with -v)')),
   349         (b'u', b'user', None, _(b'list the author (long with -v)')),
   346         ('f', 'file', None, _('list the filename')),
   350         (b'f', b'file', None, _(b'list the filename')),
   347         ('d', 'date', None, _('list the date (short with -q)')),
   351         (b'd', b'date', None, _(b'list the date (short with -q)')),
   348         ('n', 'number', None, _('list the revision number (default)')),
   352         (b'n', b'number', None, _(b'list the revision number (default)')),
   349         ('c', 'changeset', None, _('list the changeset')),
   353         (b'c', b'changeset', None, _(b'list the changeset')),
   350         (
   354         (
   351             'l',
   355             b'l',
   352             'line-number',
   356             b'line-number',
   353             None,
   357             None,
   354             _('show line number at the first appearance'),
   358             _(b'show line number at the first appearance'),
   355         ),
   359         ),
   356         ('', 'skip', [], _('revision to not display (EXPERIMENTAL)'), _('REV')),
   360         (
       
   361             b'',
       
   362             b'skip',
       
   363             [],
       
   364             _(b'revision to not display (EXPERIMENTAL)'),
       
   365             _(b'REV'),
       
   366         ),
   357     ]
   367     ]
   358     + diffwsopts
   368     + diffwsopts
   359     + walkopts
   369     + walkopts
   360     + formatteropts,
   370     + formatteropts,
   361     _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'),
   371     _(b'[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'),
   362     helpcategory=command.CATEGORY_FILE_CONTENTS,
   372     helpcategory=command.CATEGORY_FILE_CONTENTS,
   363     helpbasic=True,
   373     helpbasic=True,
   364     inferrepo=True,
   374     inferrepo=True,
   365 )
   375 )
   366 def annotate(ui, repo, *pats, **opts):
   376 def annotate(ui, repo, *pats, **opts):
   401 
   411 
   402     Returns 0 on success.
   412     Returns 0 on success.
   403     """
   413     """
   404     opts = pycompat.byteskwargs(opts)
   414     opts = pycompat.byteskwargs(opts)
   405     if not pats:
   415     if not pats:
   406         raise error.Abort(_('at least one filename or pattern is required'))
   416         raise error.Abort(_(b'at least one filename or pattern is required'))
   407 
   417 
   408     if opts.get('follow'):
   418     if opts.get(b'follow'):
   409         # --follow is deprecated and now just an alias for -f/--file
   419         # --follow is deprecated and now just an alias for -f/--file
   410         # to mimic the behavior of Mercurial before version 1.5
   420         # to mimic the behavior of Mercurial before version 1.5
   411         opts['file'] = True
   421         opts[b'file'] = True
   412 
   422 
   413     if (
   423     if (
   414         not opts.get('user')
   424         not opts.get(b'user')
   415         and not opts.get('changeset')
   425         and not opts.get(b'changeset')
   416         and not opts.get('date')
   426         and not opts.get(b'date')
   417         and not opts.get('file')
   427         and not opts.get(b'file')
   418     ):
   428     ):
   419         opts['number'] = True
   429         opts[b'number'] = True
   420 
   430 
   421     linenumber = opts.get('line_number') is not None
   431     linenumber = opts.get(b'line_number') is not None
   422     if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
   432     if (
   423         raise error.Abort(_('at least one of -n/-c is required for -l'))
   433         linenumber
   424 
   434         and (not opts.get(b'changeset'))
   425     rev = opts.get('rev')
   435         and (not opts.get(b'number'))
       
   436     ):
       
   437         raise error.Abort(_(b'at least one of -n/-c is required for -l'))
       
   438 
       
   439     rev = opts.get(b'rev')
   426     if rev:
   440     if rev:
   427         repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
   441         repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
   428     ctx = scmutil.revsingle(repo, rev)
   442     ctx = scmutil.revsingle(repo, rev)
   429 
   443 
   430     ui.pager('annotate')
   444     ui.pager(b'annotate')
   431     rootfm = ui.formatter('annotate', opts)
   445     rootfm = ui.formatter(b'annotate', opts)
   432     if ui.debugflag:
   446     if ui.debugflag:
   433         shorthex = pycompat.identity
   447         shorthex = pycompat.identity
   434     else:
   448     else:
   435 
   449 
   436         def shorthex(h):
   450         def shorthex(h):
   439     if ui.quiet:
   453     if ui.quiet:
   440         datefunc = dateutil.shortdate
   454         datefunc = dateutil.shortdate
   441     else:
   455     else:
   442         datefunc = dateutil.datestr
   456         datefunc = dateutil.datestr
   443     if ctx.rev() is None:
   457     if ctx.rev() is None:
   444         if opts.get('changeset'):
   458         if opts.get(b'changeset'):
   445             # omit "+" suffix which is appended to node hex
   459             # omit "+" suffix which is appended to node hex
   446             def formatrev(rev):
   460             def formatrev(rev):
   447                 if rev == wdirrev:
   461                 if rev == wdirrev:
   448                     return '%d' % ctx.p1().rev()
   462                     return b'%d' % ctx.p1().rev()
   449                 else:
   463                 else:
   450                     return '%d' % rev
   464                     return b'%d' % rev
   451 
   465 
   452         else:
   466         else:
   453 
   467 
   454             def formatrev(rev):
   468             def formatrev(rev):
   455                 if rev == wdirrev:
   469                 if rev == wdirrev:
   456                     return '%d+' % ctx.p1().rev()
   470                     return b'%d+' % ctx.p1().rev()
   457                 else:
   471                 else:
   458                     return '%d ' % rev
   472                     return b'%d ' % rev
   459 
   473 
   460         def formathex(h):
   474         def formathex(h):
   461             if h == wdirhex:
   475             if h == wdirhex:
   462                 return '%s+' % shorthex(hex(ctx.p1().node()))
   476                 return b'%s+' % shorthex(hex(ctx.p1().node()))
   463             else:
   477             else:
   464                 return '%s ' % shorthex(h)
   478                 return b'%s ' % shorthex(h)
   465 
   479 
   466     else:
   480     else:
   467         formatrev = b'%d'.__mod__
   481         formatrev = b'%d'.__mod__
   468         formathex = shorthex
   482         formathex = shorthex
   469 
   483 
   470     opmap = [
   484     opmap = [
   471         ('user', ' ', lambda x: x.fctx.user(), ui.shortuser),
   485         (b'user', b' ', lambda x: x.fctx.user(), ui.shortuser),
   472         ('rev', ' ', lambda x: scmutil.intrev(x.fctx), formatrev),
   486         (b'rev', b' ', lambda x: scmutil.intrev(x.fctx), formatrev),
   473         ('node', ' ', lambda x: hex(scmutil.binnode(x.fctx)), formathex),
   487         (b'node', b' ', lambda x: hex(scmutil.binnode(x.fctx)), formathex),
   474         ('date', ' ', lambda x: x.fctx.date(), util.cachefunc(datefunc)),
   488         (b'date', b' ', lambda x: x.fctx.date(), util.cachefunc(datefunc)),
   475         ('path', ' ', lambda x: x.fctx.path(), pycompat.bytestr),
   489         (b'path', b' ', lambda x: x.fctx.path(), pycompat.bytestr),
   476         ('lineno', ':', lambda x: x.lineno, pycompat.bytestr),
   490         (b'lineno', b':', lambda x: x.lineno, pycompat.bytestr),
   477     ]
   491     ]
   478     opnamemap = {
   492     opnamemap = {
   479         'rev': 'number',
   493         b'rev': b'number',
   480         'node': 'changeset',
   494         b'node': b'changeset',
   481         'path': 'file',
   495         b'path': b'file',
   482         'lineno': 'line_number',
   496         b'lineno': b'line_number',
   483     }
   497     }
   484 
   498 
   485     if rootfm.isplain():
   499     if rootfm.isplain():
   486 
   500 
   487         def makefunc(get, fmt):
   501         def makefunc(get, fmt):
   496     funcmap = [
   510     funcmap = [
   497         (makefunc(get, fmt), sep)
   511         (makefunc(get, fmt), sep)
   498         for fn, sep, get, fmt in opmap
   512         for fn, sep, get, fmt in opmap
   499         if opts.get(opnamemap.get(fn, fn)) or fn in datahint
   513         if opts.get(opnamemap.get(fn, fn)) or fn in datahint
   500     ]
   514     ]
   501     funcmap[0] = (funcmap[0][0], '')  # no separator in front of first column
   515     funcmap[0] = (funcmap[0][0], b'')  # no separator in front of first column
   502     fields = ' '.join(
   516     fields = b' '.join(
   503         fn
   517         fn
   504         for fn, sep, get, fmt in opmap
   518         for fn, sep, get, fmt in opmap
   505         if opts.get(opnamemap.get(fn, fn)) or fn in datahint
   519         if opts.get(opnamemap.get(fn, fn)) or fn in datahint
   506     )
   520     )
   507 
   521 
   508     def bad(x, y):
   522     def bad(x, y):
   509         raise error.Abort("%s: %s" % (x, y))
   523         raise error.Abort(b"%s: %s" % (x, y))
   510 
   524 
   511     m = scmutil.match(ctx, pats, opts, badfn=bad)
   525     m = scmutil.match(ctx, pats, opts, badfn=bad)
   512 
   526 
   513     follow = not opts.get('no_follow')
   527     follow = not opts.get(b'no_follow')
   514     diffopts = patch.difffeatureopts(
   528     diffopts = patch.difffeatureopts(
   515         ui, opts, section='annotate', whitespace=True
   529         ui, opts, section=b'annotate', whitespace=True
   516     )
   530     )
   517     skiprevs = opts.get('skip')
   531     skiprevs = opts.get(b'skip')
   518     if skiprevs:
   532     if skiprevs:
   519         skiprevs = scmutil.revrange(repo, skiprevs)
   533         skiprevs = scmutil.revrange(repo, skiprevs)
   520 
   534 
   521     uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
   535     uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
   522     for abs in ctx.walk(m):
   536     for abs in ctx.walk(m):
   523         fctx = ctx[abs]
   537         fctx = ctx[abs]
   524         rootfm.startitem()
   538         rootfm.startitem()
   525         rootfm.data(path=abs)
   539         rootfm.data(path=abs)
   526         if not opts.get('text') and fctx.isbinary():
   540         if not opts.get(b'text') and fctx.isbinary():
   527             rootfm.plain(_("%s: binary file\n") % uipathfn(abs))
   541             rootfm.plain(_(b"%s: binary file\n") % uipathfn(abs))
   528             continue
   542             continue
   529 
   543 
   530         fm = rootfm.nested('lines', tmpl='{rev}: {line}')
   544         fm = rootfm.nested(b'lines', tmpl=b'{rev}: {line}')
   531         lines = fctx.annotate(
   545         lines = fctx.annotate(
   532             follow=follow, skiprevs=skiprevs, diffopts=diffopts
   546             follow=follow, skiprevs=skiprevs, diffopts=diffopts
   533         )
   547         )
   534         if not lines:
   548         if not lines:
   535             fm.end()
   549             fm.end()
   540         for f, sep in funcmap:
   554         for f, sep in funcmap:
   541             l = [f(n) for n in lines]
   555             l = [f(n) for n in lines]
   542             if fm.isplain():
   556             if fm.isplain():
   543                 sizes = [encoding.colwidth(x) for x in l]
   557                 sizes = [encoding.colwidth(x) for x in l]
   544                 ml = max(sizes)
   558                 ml = max(sizes)
   545                 formats.append([sep + ' ' * (ml - w) + '%s' for w in sizes])
   559                 formats.append([sep + b' ' * (ml - w) + b'%s' for w in sizes])
   546             else:
   560             else:
   547                 formats.append(['%s' for x in l])
   561                 formats.append([b'%s' for x in l])
   548             pieces.append(l)
   562             pieces.append(l)
   549 
   563 
   550         for f, p, n in zip(zip(*formats), zip(*pieces), lines):
   564         for f, p, n in zip(zip(*formats), zip(*pieces), lines):
   551             fm.startitem()
   565             fm.startitem()
   552             fm.context(fctx=n.fctx)
   566             fm.context(fctx=n.fctx)
   553             fm.write(fields, "".join(f), *p)
   567             fm.write(fields, b"".join(f), *p)
   554             if n.skip:
   568             if n.skip:
   555                 fmt = "* %s"
   569                 fmt = b"* %s"
   556             else:
   570             else:
   557                 fmt = ": %s"
   571                 fmt = b": %s"
   558             fm.write('line', fmt, n.text)
   572             fm.write(b'line', fmt, n.text)
   559 
   573 
   560         if not lines[-1].text.endswith('\n'):
   574         if not lines[-1].text.endswith(b'\n'):
   561             fm.plain('\n')
   575             fm.plain(b'\n')
   562         fm.end()
   576         fm.end()
   563 
   577 
   564     rootfm.end()
   578     rootfm.end()
   565 
   579 
   566 
   580 
   567 @command(
   581 @command(
   568     'archive',
   582     b'archive',
   569     [
   583     [
   570         ('', 'no-decode', None, _('do not pass files through decoders')),
   584         (b'', b'no-decode', None, _(b'do not pass files through decoders')),
   571         (
   585         (
   572             'p',
   586             b'p',
   573             'prefix',
   587             b'prefix',
   574             '',
   588             b'',
   575             _('directory prefix for files in archive'),
   589             _(b'directory prefix for files in archive'),
   576             _('PREFIX'),
   590             _(b'PREFIX'),
   577         ),
   591         ),
   578         ('r', 'rev', '', _('revision to distribute'), _('REV')),
   592         (b'r', b'rev', b'', _(b'revision to distribute'), _(b'REV')),
   579         ('t', 'type', '', _('type of distribution to create'), _('TYPE')),
   593         (b't', b'type', b'', _(b'type of distribution to create'), _(b'TYPE')),
   580     ]
   594     ]
   581     + subrepoopts
   595     + subrepoopts
   582     + walkopts,
   596     + walkopts,
   583     _('[OPTION]... DEST'),
   597     _(b'[OPTION]... DEST'),
   584     helpcategory=command.CATEGORY_IMPORT_EXPORT,
   598     helpcategory=command.CATEGORY_IMPORT_EXPORT,
   585 )
   599 )
   586 def archive(ui, repo, dest, **opts):
   600 def archive(ui, repo, dest, **opts):
   587     '''create an unversioned archive of a repository revision
   601     '''create an unversioned archive of a repository revision
   588 
   602 
   624 
   638 
   625     Returns 0 on success.
   639     Returns 0 on success.
   626     '''
   640     '''
   627 
   641 
   628     opts = pycompat.byteskwargs(opts)
   642     opts = pycompat.byteskwargs(opts)
   629     rev = opts.get('rev')
   643     rev = opts.get(b'rev')
   630     if rev:
   644     if rev:
   631         repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
   645         repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
   632     ctx = scmutil.revsingle(repo, rev)
   646     ctx = scmutil.revsingle(repo, rev)
   633     if not ctx:
   647     if not ctx:
   634         raise error.Abort(_('no working directory: please specify a revision'))
   648         raise error.Abort(_(b'no working directory: please specify a revision'))
   635     node = ctx.node()
   649     node = ctx.node()
   636     dest = cmdutil.makefilename(ctx, dest)
   650     dest = cmdutil.makefilename(ctx, dest)
   637     if os.path.realpath(dest) == repo.root:
   651     if os.path.realpath(dest) == repo.root:
   638         raise error.Abort(_('repository root cannot be destination'))
   652         raise error.Abort(_(b'repository root cannot be destination'))
   639 
   653 
   640     kind = opts.get('type') or archival.guesskind(dest) or 'files'
   654     kind = opts.get(b'type') or archival.guesskind(dest) or b'files'
   641     prefix = opts.get('prefix')
   655     prefix = opts.get(b'prefix')
   642 
   656 
   643     if dest == '-':
   657     if dest == b'-':
   644         if kind == 'files':
   658         if kind == b'files':
   645             raise error.Abort(_('cannot archive plain files to stdout'))
   659             raise error.Abort(_(b'cannot archive plain files to stdout'))
   646         dest = cmdutil.makefileobj(ctx, dest)
   660         dest = cmdutil.makefileobj(ctx, dest)
   647         if not prefix:
   661         if not prefix:
   648             prefix = os.path.basename(repo.root) + '-%h'
   662             prefix = os.path.basename(repo.root) + b'-%h'
   649 
   663 
   650     prefix = cmdutil.makefilename(ctx, prefix)
   664     prefix = cmdutil.makefilename(ctx, prefix)
   651     match = scmutil.match(ctx, [], opts)
   665     match = scmutil.match(ctx, [], opts)
   652     archival.archive(
   666     archival.archive(
   653         repo,
   667         repo,
   654         dest,
   668         dest,
   655         node,
   669         node,
   656         kind,
   670         kind,
   657         not opts.get('no_decode'),
   671         not opts.get(b'no_decode'),
   658         match,
   672         match,
   659         prefix,
   673         prefix,
   660         subrepos=opts.get('subrepos'),
   674         subrepos=opts.get(b'subrepos'),
   661     )
   675     )
   662 
   676 
   663 
   677 
   664 @command(
   678 @command(
   665     'backout',
   679     b'backout',
   666     [
   680     [
   667         ('', 'merge', None, _('merge with old dirstate parent after backout')),
   681         (
   668         (
   682             b'',
   669             '',
   683             b'merge',
   670             'commit',
       
   671             None,
   684             None,
   672             _('commit if no conflicts were encountered (DEPRECATED)'),
   685             _(b'merge with old dirstate parent after backout'),
   673         ),
   686         ),
   674         ('', 'no-commit', None, _('do not commit')),
   687         (
   675         (
   688             b'',
   676             '',
   689             b'commit',
   677             'parent',
   690             None,
   678             '',
   691             _(b'commit if no conflicts were encountered (DEPRECATED)'),
   679             _('parent to choose when backing out merge (DEPRECATED)'),
   692         ),
   680             _('REV'),
   693         (b'', b'no-commit', None, _(b'do not commit')),
   681         ),
   694         (
   682         ('r', 'rev', '', _('revision to backout'), _('REV')),
   695             b'',
   683         ('e', 'edit', False, _('invoke editor on commit messages')),
   696             b'parent',
       
   697             b'',
       
   698             _(b'parent to choose when backing out merge (DEPRECATED)'),
       
   699             _(b'REV'),
       
   700         ),
       
   701         (b'r', b'rev', b'', _(b'revision to backout'), _(b'REV')),
       
   702         (b'e', b'edit', False, _(b'invoke editor on commit messages')),
   684     ]
   703     ]
   685     + mergetoolopts
   704     + mergetoolopts
   686     + walkopts
   705     + walkopts
   687     + commitopts
   706     + commitopts
   688     + commitopts2,
   707     + commitopts2,
   689     _('[OPTION]... [-r] REV'),
   708     _(b'[OPTION]... [-r] REV'),
   690     helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
   709     helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
   691 )
   710 )
   692 def backout(ui, repo, node=None, rev=None, **opts):
   711 def backout(ui, repo, node=None, rev=None, **opts):
   693     '''reverse effect of earlier changeset
   712     '''reverse effect of earlier changeset
   694 
   713 
   745         return _dobackout(ui, repo, node, rev, **opts)
   764         return _dobackout(ui, repo, node, rev, **opts)
   746 
   765 
   747 
   766 
   748 def _dobackout(ui, repo, node=None, rev=None, **opts):
   767 def _dobackout(ui, repo, node=None, rev=None, **opts):
   749     opts = pycompat.byteskwargs(opts)
   768     opts = pycompat.byteskwargs(opts)
   750     if opts.get('commit') and opts.get('no_commit'):
   769     if opts.get(b'commit') and opts.get(b'no_commit'):
   751         raise error.Abort(_("cannot use --commit with --no-commit"))
   770         raise error.Abort(_(b"cannot use --commit with --no-commit"))
   752     if opts.get('merge') and opts.get('no_commit'):
   771     if opts.get(b'merge') and opts.get(b'no_commit'):
   753         raise error.Abort(_("cannot use --merge with --no-commit"))
   772         raise error.Abort(_(b"cannot use --merge with --no-commit"))
   754 
   773 
   755     if rev and node:
   774     if rev and node:
   756         raise error.Abort(_("please specify just one revision"))
   775         raise error.Abort(_(b"please specify just one revision"))
   757 
   776 
   758     if not rev:
   777     if not rev:
   759         rev = node
   778         rev = node
   760 
   779 
   761     if not rev:
   780     if not rev:
   762         raise error.Abort(_("please specify a revision to backout"))
   781         raise error.Abort(_(b"please specify a revision to backout"))
   763 
   782 
   764     date = opts.get('date')
   783     date = opts.get(b'date')
   765     if date:
   784     if date:
   766         opts['date'] = dateutil.parsedate(date)
   785         opts[b'date'] = dateutil.parsedate(date)
   767 
   786 
   768     cmdutil.checkunfinished(repo)
   787     cmdutil.checkunfinished(repo)
   769     cmdutil.bailifchanged(repo)
   788     cmdutil.bailifchanged(repo)
   770     node = scmutil.revsingle(repo, rev).node()
   789     node = scmutil.revsingle(repo, rev).node()
   771 
   790 
   772     op1, op2 = repo.dirstate.parents()
   791     op1, op2 = repo.dirstate.parents()
   773     if not repo.changelog.isancestor(node, op1):
   792     if not repo.changelog.isancestor(node, op1):
   774         raise error.Abort(_('cannot backout change that is not an ancestor'))
   793         raise error.Abort(_(b'cannot backout change that is not an ancestor'))
   775 
   794 
   776     p1, p2 = repo.changelog.parents(node)
   795     p1, p2 = repo.changelog.parents(node)
   777     if p1 == nullid:
   796     if p1 == nullid:
   778         raise error.Abort(_('cannot backout a change with no parents'))
   797         raise error.Abort(_(b'cannot backout a change with no parents'))
   779     if p2 != nullid:
   798     if p2 != nullid:
   780         if not opts.get('parent'):
   799         if not opts.get(b'parent'):
   781             raise error.Abort(_('cannot backout a merge changeset'))
   800             raise error.Abort(_(b'cannot backout a merge changeset'))
   782         p = repo.lookup(opts['parent'])
   801         p = repo.lookup(opts[b'parent'])
   783         if p not in (p1, p2):
   802         if p not in (p1, p2):
   784             raise error.Abort(
   803             raise error.Abort(
   785                 _('%s is not a parent of %s') % (short(p), short(node))
   804                 _(b'%s is not a parent of %s') % (short(p), short(node))
   786             )
   805             )
   787         parent = p
   806         parent = p
   788     else:
   807     else:
   789         if opts.get('parent'):
   808         if opts.get(b'parent'):
   790             raise error.Abort(_('cannot use --parent on non-merge changeset'))
   809             raise error.Abort(_(b'cannot use --parent on non-merge changeset'))
   791         parent = p1
   810         parent = p1
   792 
   811 
   793     # the backout should appear on the same branch
   812     # the backout should appear on the same branch
   794     branch = repo.dirstate.branch()
   813     branch = repo.dirstate.branch()
   795     bheads = repo.branchheads(branch)
   814     bheads = repo.branchheads(branch)
   796     rctx = scmutil.revsingle(repo, hex(parent))
   815     rctx = scmutil.revsingle(repo, hex(parent))
   797     if not opts.get('merge') and op1 != node:
   816     if not opts.get(b'merge') and op1 != node:
   798         with dirstateguard.dirstateguard(repo, 'backout'):
   817         with dirstateguard.dirstateguard(repo, b'backout'):
   799             overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
   818             overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
   800             with ui.configoverride(overrides, 'backout'):
   819             with ui.configoverride(overrides, b'backout'):
   801                 stats = mergemod.update(
   820                 stats = mergemod.update(
   802                     repo,
   821                     repo,
   803                     parent,
   822                     parent,
   804                     branchmerge=True,
   823                     branchmerge=True,
   805                     force=True,
   824                     force=True,
   808                 )
   827                 )
   809             repo.setparents(op1, op2)
   828             repo.setparents(op1, op2)
   810         hg._showstats(repo, stats)
   829         hg._showstats(repo, stats)
   811         if stats.unresolvedcount:
   830         if stats.unresolvedcount:
   812             repo.ui.status(
   831             repo.ui.status(
   813                 _("use 'hg resolve' to retry unresolved " "file merges\n")
   832                 _(b"use 'hg resolve' to retry unresolved " b"file merges\n")
   814             )
   833             )
   815             return 1
   834             return 1
   816     else:
   835     else:
   817         hg.clean(repo, node, show_stats=False)
   836         hg.clean(repo, node, show_stats=False)
   818         repo.dirstate.setbranch(branch)
   837         repo.dirstate.setbranch(branch)
   819         cmdutil.revert(ui, repo, rctx, repo.dirstate.parents())
   838         cmdutil.revert(ui, repo, rctx, repo.dirstate.parents())
   820 
   839 
   821     if opts.get('no_commit'):
   840     if opts.get(b'no_commit'):
   822         msg = _("changeset %s backed out, " "don't forget to commit.\n")
   841         msg = _(b"changeset %s backed out, " b"don't forget to commit.\n")
   823         ui.status(msg % short(node))
   842         ui.status(msg % short(node))
   824         return 0
   843         return 0
   825 
   844 
   826     def commitfunc(ui, repo, message, match, opts):
   845     def commitfunc(ui, repo, message, match, opts):
   827         editform = 'backout'
   846         editform = b'backout'
   828         e = cmdutil.getcommiteditor(
   847         e = cmdutil.getcommiteditor(
   829             editform=editform, **pycompat.strkwargs(opts)
   848             editform=editform, **pycompat.strkwargs(opts)
   830         )
   849         )
   831         if not message:
   850         if not message:
   832             # we don't translate commit messages
   851             # we don't translate commit messages
   833             message = "Backed out changeset %s" % short(node)
   852             message = b"Backed out changeset %s" % short(node)
   834             e = cmdutil.getcommiteditor(edit=True, editform=editform)
   853             e = cmdutil.getcommiteditor(edit=True, editform=editform)
   835         return repo.commit(
   854         return repo.commit(
   836             message, opts.get('user'), opts.get('date'), match, editor=e
   855             message, opts.get(b'user'), opts.get(b'date'), match, editor=e
   837         )
   856         )
   838 
   857 
   839     newnode = cmdutil.commit(ui, repo, commitfunc, [], opts)
   858     newnode = cmdutil.commit(ui, repo, commitfunc, [], opts)
   840     if not newnode:
   859     if not newnode:
   841         ui.status(_("nothing changed\n"))
   860         ui.status(_(b"nothing changed\n"))
   842         return 1
   861         return 1
   843     cmdutil.commitstatus(repo, newnode, branch, bheads)
   862     cmdutil.commitstatus(repo, newnode, branch, bheads)
   844 
   863 
   845     def nice(node):
   864     def nice(node):
   846         return '%d:%s' % (repo.changelog.rev(node), short(node))
   865         return b'%d:%s' % (repo.changelog.rev(node), short(node))
   847 
   866 
   848     ui.status(
   867     ui.status(
   849         _('changeset %s backs out changeset %s\n')
   868         _(b'changeset %s backs out changeset %s\n')
   850         % (nice(repo.changelog.tip()), nice(node))
   869         % (nice(repo.changelog.tip()), nice(node))
   851     )
   870     )
   852     if opts.get('merge') and op1 != node:
   871     if opts.get(b'merge') and op1 != node:
   853         hg.clean(repo, op1, show_stats=False)
   872         hg.clean(repo, op1, show_stats=False)
   854         ui.status(_('merging with changeset %s\n') % nice(repo.changelog.tip()))
   873         ui.status(
   855         overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
   874             _(b'merging with changeset %s\n') % nice(repo.changelog.tip())
   856         with ui.configoverride(overrides, 'backout'):
   875         )
       
   876         overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
       
   877         with ui.configoverride(overrides, b'backout'):
   857             return hg.merge(repo, hex(repo.changelog.tip()))
   878             return hg.merge(repo, hex(repo.changelog.tip()))
   858     return 0
   879     return 0
   859 
   880 
   860 
   881 
   861 @command(
   882 @command(
   862     'bisect',
   883     b'bisect',
   863     [
   884     [
   864         ('r', 'reset', False, _('reset bisect state')),
   885         (b'r', b'reset', False, _(b'reset bisect state')),
   865         ('g', 'good', False, _('mark changeset good')),
   886         (b'g', b'good', False, _(b'mark changeset good')),
   866         ('b', 'bad', False, _('mark changeset bad')),
   887         (b'b', b'bad', False, _(b'mark changeset bad')),
   867         ('s', 'skip', False, _('skip testing changeset')),
   888         (b's', b'skip', False, _(b'skip testing changeset')),
   868         ('e', 'extend', False, _('extend the bisect range')),
   889         (b'e', b'extend', False, _(b'extend the bisect range')),
   869         (
   890         (
   870             'c',
   891             b'c',
   871             'command',
   892             b'command',
   872             '',
   893             b'',
   873             _('use command to check changeset state'),
   894             _(b'use command to check changeset state'),
   874             _('CMD'),
   895             _(b'CMD'),
   875         ),
   896         ),
   876         ('U', 'noupdate', False, _('do not update to target')),
   897         (b'U', b'noupdate', False, _(b'do not update to target')),
   877     ],
   898     ],
   878     _("[-gbsr] [-U] [-c CMD] [REV]"),
   899     _(b"[-gbsr] [-U] [-c CMD] [REV]"),
   879     helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
   900     helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
   880 )
   901 )
   881 def bisect(
   902 def bisect(
   882     ui,
   903     ui,
   883     repo,
   904     repo,
   971       See :hg:`help revisions.bisect` for more about the `bisect()` predicate.
   992       See :hg:`help revisions.bisect` for more about the `bisect()` predicate.
   972 
   993 
   973     Returns 0 on success.
   994     Returns 0 on success.
   974     """
   995     """
   975     # backward compatibility
   996     # backward compatibility
   976     if rev in "good bad reset init".split():
   997     if rev in b"good bad reset init".split():
   977         ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
   998         ui.warn(_(b"(use of 'hg bisect <cmd>' is deprecated)\n"))
   978         cmd, rev, extra = rev, extra, None
   999         cmd, rev, extra = rev, extra, None
   979         if cmd == "good":
  1000         if cmd == b"good":
   980             good = True
  1001             good = True
   981         elif cmd == "bad":
  1002         elif cmd == b"bad":
   982             bad = True
  1003             bad = True
   983         else:
  1004         else:
   984             reset = True
  1005             reset = True
   985     elif extra:
  1006     elif extra:
   986         raise error.Abort(_('incompatible arguments'))
  1007         raise error.Abort(_(b'incompatible arguments'))
   987 
  1008 
   988     incompatibles = {
  1009     incompatibles = {
   989         '--bad': bad,
  1010         b'--bad': bad,
   990         '--command': bool(command),
  1011         b'--command': bool(command),
   991         '--extend': extend,
  1012         b'--extend': extend,
   992         '--good': good,
  1013         b'--good': good,
   993         '--reset': reset,
  1014         b'--reset': reset,
   994         '--skip': skip,
  1015         b'--skip': skip,
   995     }
  1016     }
   996 
  1017 
   997     enabled = [x for x in incompatibles if incompatibles[x]]
  1018     enabled = [x for x in incompatibles if incompatibles[x]]
   998 
  1019 
   999     if len(enabled) > 1:
  1020     if len(enabled) > 1:
  1000         raise error.Abort(
  1021         raise error.Abort(
  1001             _('%s and %s are incompatible') % tuple(sorted(enabled)[0:2])
  1022             _(b'%s and %s are incompatible') % tuple(sorted(enabled)[0:2])
  1002         )
  1023         )
  1003 
  1024 
  1004     if reset:
  1025     if reset:
  1005         hbisect.resetstate(repo)
  1026         hbisect.resetstate(repo)
  1006         return
  1027         return
  1010     # update state
  1031     # update state
  1011     if good or bad or skip:
  1032     if good or bad or skip:
  1012         if rev:
  1033         if rev:
  1013             nodes = [repo[i].node() for i in scmutil.revrange(repo, [rev])]
  1034             nodes = [repo[i].node() for i in scmutil.revrange(repo, [rev])]
  1014         else:
  1035         else:
  1015             nodes = [repo.lookup('.')]
  1036             nodes = [repo.lookup(b'.')]
  1016         if good:
  1037         if good:
  1017             state['good'] += nodes
  1038             state[b'good'] += nodes
  1018         elif bad:
  1039         elif bad:
  1019             state['bad'] += nodes
  1040             state[b'bad'] += nodes
  1020         elif skip:
  1041         elif skip:
  1021             state['skip'] += nodes
  1042             state[b'skip'] += nodes
  1022         hbisect.save_state(repo, state)
  1043         hbisect.save_state(repo, state)
  1023         if not (state['good'] and state['bad']):
  1044         if not (state[b'good'] and state[b'bad']):
  1024             return
  1045             return
  1025 
  1046 
  1026     def mayupdate(repo, node, show_stats=True):
  1047     def mayupdate(repo, node, show_stats=True):
  1027         """common used update sequence"""
  1048         """common used update sequence"""
  1028         if noupdate:
  1049         if noupdate:
  1035 
  1056 
  1036     if command:
  1057     if command:
  1037         changesets = 1
  1058         changesets = 1
  1038         if noupdate:
  1059         if noupdate:
  1039             try:
  1060             try:
  1040                 node = state['current'][0]
  1061                 node = state[b'current'][0]
  1041             except LookupError:
  1062             except LookupError:
  1042                 raise error.Abort(
  1063                 raise error.Abort(
  1043                     _(
  1064                     _(
  1044                         'current bisect revision is unknown - '
  1065                         b'current bisect revision is unknown - '
  1045                         'start a new bisect to fix'
  1066                         b'start a new bisect to fix'
  1046                     )
  1067                     )
  1047                 )
  1068                 )
  1048         else:
  1069         else:
  1049             node, p2 = repo.dirstate.parents()
  1070             node, p2 = repo.dirstate.parents()
  1050             if p2 != nullid:
  1071             if p2 != nullid:
  1051                 raise error.Abort(_('current bisect revision is a merge'))
  1072                 raise error.Abort(_(b'current bisect revision is a merge'))
  1052         if rev:
  1073         if rev:
  1053             node = repo[scmutil.revsingle(repo, rev, node)].node()
  1074             node = repo[scmutil.revsingle(repo, rev, node)].node()
  1054         try:
  1075         try:
  1055             while changesets:
  1076             while changesets:
  1056                 # update state
  1077                 # update state
  1057                 state['current'] = [node]
  1078                 state[b'current'] = [node]
  1058                 hbisect.save_state(repo, state)
  1079                 hbisect.save_state(repo, state)
  1059                 status = ui.system(
  1080                 status = ui.system(
  1060                     command,
  1081                     command,
  1061                     environ={'HG_NODE': hex(node)},
  1082                     environ={b'HG_NODE': hex(node)},
  1062                     blockedtag='bisect_check',
  1083                     blockedtag=b'bisect_check',
  1063                 )
  1084                 )
  1064                 if status == 125:
  1085                 if status == 125:
  1065                     transition = "skip"
  1086                     transition = b"skip"
  1066                 elif status == 0:
  1087                 elif status == 0:
  1067                     transition = "good"
  1088                     transition = b"good"
  1068                 # status < 0 means process was killed
  1089                 # status < 0 means process was killed
  1069                 elif status == 127:
  1090                 elif status == 127:
  1070                     raise error.Abort(_("failed to execute %s") % command)
  1091                     raise error.Abort(_(b"failed to execute %s") % command)
  1071                 elif status < 0:
  1092                 elif status < 0:
  1072                     raise error.Abort(_("%s killed") % command)
  1093                     raise error.Abort(_(b"%s killed") % command)
  1073                 else:
  1094                 else:
  1074                     transition = "bad"
  1095                     transition = b"bad"
  1075                 state[transition].append(node)
  1096                 state[transition].append(node)
  1076                 ctx = repo[node]
  1097                 ctx = repo[node]
  1077                 ui.status(
  1098                 ui.status(
  1078                     _('changeset %d:%s: %s\n') % (ctx.rev(), ctx, transition)
  1099                     _(b'changeset %d:%s: %s\n') % (ctx.rev(), ctx, transition)
  1079                 )
  1100                 )
  1080                 hbisect.checkstate(state)
  1101                 hbisect.checkstate(state)
  1081                 # bisect
  1102                 # bisect
  1082                 nodes, changesets, bgood = hbisect.bisect(repo, state)
  1103                 nodes, changesets, bgood = hbisect.bisect(repo, state)
  1083                 # update to next check
  1104                 # update to next check
  1084                 node = nodes[0]
  1105                 node = nodes[0]
  1085                 mayupdate(repo, node, show_stats=False)
  1106                 mayupdate(repo, node, show_stats=False)
  1086         finally:
  1107         finally:
  1087             state['current'] = [node]
  1108             state[b'current'] = [node]
  1088             hbisect.save_state(repo, state)
  1109             hbisect.save_state(repo, state)
  1089         hbisect.printresult(ui, repo, state, displayer, nodes, bgood)
  1110         hbisect.printresult(ui, repo, state, displayer, nodes, bgood)
  1090         return
  1111         return
  1091 
  1112 
  1092     hbisect.checkstate(state)
  1113     hbisect.checkstate(state)
  1096     if extend:
  1117     if extend:
  1097         if not changesets:
  1118         if not changesets:
  1098             extendnode = hbisect.extendrange(repo, state, nodes, good)
  1119             extendnode = hbisect.extendrange(repo, state, nodes, good)
  1099             if extendnode is not None:
  1120             if extendnode is not None:
  1100                 ui.write(
  1121                 ui.write(
  1101                     _("Extending search to changeset %d:%s\n")
  1122                     _(b"Extending search to changeset %d:%s\n")
  1102                     % (extendnode.rev(), extendnode)
  1123                     % (extendnode.rev(), extendnode)
  1103                 )
  1124                 )
  1104                 state['current'] = [extendnode.node()]
  1125                 state[b'current'] = [extendnode.node()]
  1105                 hbisect.save_state(repo, state)
  1126                 hbisect.save_state(repo, state)
  1106                 return mayupdate(repo, extendnode.node())
  1127                 return mayupdate(repo, extendnode.node())
  1107         raise error.Abort(_("nothing to extend"))
  1128         raise error.Abort(_(b"nothing to extend"))
  1108 
  1129 
  1109     if changesets == 0:
  1130     if changesets == 0:
  1110         hbisect.printresult(ui, repo, state, displayer, nodes, good)
  1131         hbisect.printresult(ui, repo, state, displayer, nodes, good)
  1111     else:
  1132     else:
  1112         assert len(nodes) == 1  # only a single node can be tested next
  1133         assert len(nodes) == 1  # only a single node can be tested next
  1116         while size <= changesets:
  1137         while size <= changesets:
  1117             tests, size = tests + 1, size * 2
  1138             tests, size = tests + 1, size * 2
  1118         rev = repo.changelog.rev(node)
  1139         rev = repo.changelog.rev(node)
  1119         ui.write(
  1140         ui.write(
  1120             _(
  1141             _(
  1121                 "Testing changeset %d:%s "
  1142                 b"Testing changeset %d:%s "
  1122                 "(%d changesets remaining, ~%d tests)\n"
  1143                 b"(%d changesets remaining, ~%d tests)\n"
  1123             )
  1144             )
  1124             % (rev, short(node), changesets, tests)
  1145             % (rev, short(node), changesets, tests)
  1125         )
  1146         )
  1126         state['current'] = [node]
  1147         state[b'current'] = [node]
  1127         hbisect.save_state(repo, state)
  1148         hbisect.save_state(repo, state)
  1128         return mayupdate(repo, node)
  1149         return mayupdate(repo, node)
  1129 
  1150 
  1130 
  1151 
  1131 @command(
  1152 @command(
  1132     'bookmarks|bookmark',
  1153     b'bookmarks|bookmark',
  1133     [
  1154     [
  1134         ('f', 'force', False, _('force')),
  1155         (b'f', b'force', False, _(b'force')),
  1135         ('r', 'rev', '', _('revision for bookmark action'), _('REV')),
  1156         (b'r', b'rev', b'', _(b'revision for bookmark action'), _(b'REV')),
  1136         ('d', 'delete', False, _('delete a given bookmark')),
  1157         (b'd', b'delete', False, _(b'delete a given bookmark')),
  1137         ('m', 'rename', '', _('rename a given bookmark'), _('OLD')),
  1158         (b'm', b'rename', b'', _(b'rename a given bookmark'), _(b'OLD')),
  1138         ('i', 'inactive', False, _('mark a bookmark inactive')),
  1159         (b'i', b'inactive', False, _(b'mark a bookmark inactive')),
  1139         ('l', 'list', False, _('list existing bookmarks')),
  1160         (b'l', b'list', False, _(b'list existing bookmarks')),
  1140     ]
  1161     ]
  1141     + formatteropts,
  1162     + formatteropts,
  1142     _('hg bookmarks [OPTIONS]... [NAME]...'),
  1163     _(b'hg bookmarks [OPTIONS]... [NAME]...'),
  1143     helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
  1164     helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
  1144 )
  1165 )
  1145 def bookmark(ui, repo, *names, **opts):
  1166 def bookmark(ui, repo, *names, **opts):
  1146     '''create a new bookmark or list existing bookmarks
  1167     '''create a new bookmark or list existing bookmarks
  1147 
  1168 
  1201       - print only the active bookmark name::
  1222       - print only the active bookmark name::
  1202 
  1223 
  1203           hg book -ql .
  1224           hg book -ql .
  1204     '''
  1225     '''
  1205     opts = pycompat.byteskwargs(opts)
  1226     opts = pycompat.byteskwargs(opts)
  1206     force = opts.get('force')
  1227     force = opts.get(b'force')
  1207     rev = opts.get('rev')
  1228     rev = opts.get(b'rev')
  1208     inactive = opts.get('inactive')  # meaning add/rename to inactive bookmark
  1229     inactive = opts.get(b'inactive')  # meaning add/rename to inactive bookmark
  1209 
  1230 
  1210     selactions = [k for k in ['delete', 'rename', 'list'] if opts.get(k)]
  1231     selactions = [k for k in [b'delete', b'rename', b'list'] if opts.get(k)]
  1211     if len(selactions) > 1:
  1232     if len(selactions) > 1:
  1212         raise error.Abort(
  1233         raise error.Abort(
  1213             _('--%s and --%s are incompatible') % tuple(selactions[:2])
  1234             _(b'--%s and --%s are incompatible') % tuple(selactions[:2])
  1214         )
  1235         )
  1215     if selactions:
  1236     if selactions:
  1216         action = selactions[0]
  1237         action = selactions[0]
  1217     elif names or rev:
  1238     elif names or rev:
  1218         action = 'add'
  1239         action = b'add'
  1219     elif inactive:
  1240     elif inactive:
  1220         action = 'inactive'  # meaning deactivate
  1241         action = b'inactive'  # meaning deactivate
  1221     else:
  1242     else:
  1222         action = 'list'
  1243         action = b'list'
  1223 
  1244 
  1224     if rev and action in {'delete', 'rename', 'list'}:
  1245     if rev and action in {b'delete', b'rename', b'list'}:
  1225         raise error.Abort(_("--rev is incompatible with --%s") % action)
  1246         raise error.Abort(_(b"--rev is incompatible with --%s") % action)
  1226     if inactive and action in {'delete', 'list'}:
  1247     if inactive and action in {b'delete', b'list'}:
  1227         raise error.Abort(_("--inactive is incompatible with --%s") % action)
  1248         raise error.Abort(_(b"--inactive is incompatible with --%s") % action)
  1228     if not names and action in {'add', 'delete'}:
  1249     if not names and action in {b'add', b'delete'}:
  1229         raise error.Abort(_("bookmark name required"))
  1250         raise error.Abort(_(b"bookmark name required"))
  1230 
  1251 
  1231     if action in {'add', 'delete', 'rename', 'inactive'}:
  1252     if action in {b'add', b'delete', b'rename', b'inactive'}:
  1232         with repo.wlock(), repo.lock(), repo.transaction('bookmark') as tr:
  1253         with repo.wlock(), repo.lock(), repo.transaction(b'bookmark') as tr:
  1233             if action == 'delete':
  1254             if action == b'delete':
  1234                 names = pycompat.maplist(repo._bookmarks.expandname, names)
  1255                 names = pycompat.maplist(repo._bookmarks.expandname, names)
  1235                 bookmarks.delete(repo, tr, names)
  1256                 bookmarks.delete(repo, tr, names)
  1236             elif action == 'rename':
  1257             elif action == b'rename':
  1237                 if not names:
  1258                 if not names:
  1238                     raise error.Abort(_("new bookmark name required"))
  1259                     raise error.Abort(_(b"new bookmark name required"))
  1239                 elif len(names) > 1:
  1260                 elif len(names) > 1:
  1240                     raise error.Abort(_("only one new bookmark name allowed"))
  1261                     raise error.Abort(_(b"only one new bookmark name allowed"))
  1241                 oldname = repo._bookmarks.expandname(opts['rename'])
  1262                 oldname = repo._bookmarks.expandname(opts[b'rename'])
  1242                 bookmarks.rename(repo, tr, oldname, names[0], force, inactive)
  1263                 bookmarks.rename(repo, tr, oldname, names[0], force, inactive)
  1243             elif action == 'add':
  1264             elif action == b'add':
  1244                 bookmarks.addbookmarks(repo, tr, names, rev, force, inactive)
  1265                 bookmarks.addbookmarks(repo, tr, names, rev, force, inactive)
  1245             elif action == 'inactive':
  1266             elif action == b'inactive':
  1246                 if len(repo._bookmarks) == 0:
  1267                 if len(repo._bookmarks) == 0:
  1247                     ui.status(_("no bookmarks set\n"))
  1268                     ui.status(_(b"no bookmarks set\n"))
  1248                 elif not repo._activebookmark:
  1269                 elif not repo._activebookmark:
  1249                     ui.status(_("no active bookmark\n"))
  1270                     ui.status(_(b"no active bookmark\n"))
  1250                 else:
  1271                 else:
  1251                     bookmarks.deactivate(repo)
  1272                     bookmarks.deactivate(repo)
  1252     elif action == 'list':
  1273     elif action == b'list':
  1253         names = pycompat.maplist(repo._bookmarks.expandname, names)
  1274         names = pycompat.maplist(repo._bookmarks.expandname, names)
  1254         with ui.formatter('bookmarks', opts) as fm:
  1275         with ui.formatter(b'bookmarks', opts) as fm:
  1255             bookmarks.printbookmarks(ui, repo, fm, names)
  1276             bookmarks.printbookmarks(ui, repo, fm, names)
  1256     else:
  1277     else:
  1257         raise error.ProgrammingError('invalid action: %s' % action)
  1278         raise error.ProgrammingError(b'invalid action: %s' % action)
  1258 
  1279 
  1259 
  1280 
  1260 @command(
  1281 @command(
  1261     'branch',
  1282     b'branch',
  1262     [
  1283     [
  1263         (
  1284         (
  1264             'f',
  1285             b'f',
  1265             'force',
  1286             b'force',
  1266             None,
  1287             None,
  1267             _('set branch name even if it shadows an existing branch'),
  1288             _(b'set branch name even if it shadows an existing branch'),
  1268         ),
  1289         ),
  1269         ('C', 'clean', None, _('reset branch name to parent branch name')),
  1290         (b'C', b'clean', None, _(b'reset branch name to parent branch name')),
  1270         ('r', 'rev', [], _('change branches of the given revs (EXPERIMENTAL)')),
  1291         (
       
  1292             b'r',
       
  1293             b'rev',
       
  1294             [],
       
  1295             _(b'change branches of the given revs (EXPERIMENTAL)'),
       
  1296         ),
  1271     ],
  1297     ],
  1272     _('[-fC] [NAME]'),
  1298     _(b'[-fC] [NAME]'),
  1273     helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
  1299     helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
  1274 )
  1300 )
  1275 def branch(ui, repo, label=None, **opts):
  1301 def branch(ui, repo, label=None, **opts):
  1276     """set or show the current branch name
  1302     """set or show the current branch name
  1277 
  1303 
  1300     considered closed.
  1326     considered closed.
  1301 
  1327 
  1302     Returns 0 on success.
  1328     Returns 0 on success.
  1303     """
  1329     """
  1304     opts = pycompat.byteskwargs(opts)
  1330     opts = pycompat.byteskwargs(opts)
  1305     revs = opts.get('rev')
  1331     revs = opts.get(b'rev')
  1306     if label:
  1332     if label:
  1307         label = label.strip()
  1333         label = label.strip()
  1308 
  1334 
  1309     if not opts.get('clean') and not label:
  1335     if not opts.get(b'clean') and not label:
  1310         if revs:
  1336         if revs:
  1311             raise error.Abort(_("no branch name specified for the revisions"))
  1337             raise error.Abort(_(b"no branch name specified for the revisions"))
  1312         ui.write("%s\n" % repo.dirstate.branch())
  1338         ui.write(b"%s\n" % repo.dirstate.branch())
  1313         return
  1339         return
  1314 
  1340 
  1315     with repo.wlock():
  1341     with repo.wlock():
  1316         if opts.get('clean'):
  1342         if opts.get(b'clean'):
  1317             label = repo['.'].branch()
  1343             label = repo[b'.'].branch()
  1318             repo.dirstate.setbranch(label)
  1344             repo.dirstate.setbranch(label)
  1319             ui.status(_('reset working directory to branch %s\n') % label)
  1345             ui.status(_(b'reset working directory to branch %s\n') % label)
  1320         elif label:
  1346         elif label:
  1321 
  1347 
  1322             scmutil.checknewlabel(repo, label, 'branch')
  1348             scmutil.checknewlabel(repo, label, b'branch')
  1323             if revs:
  1349             if revs:
  1324                 return cmdutil.changebranch(ui, repo, revs, label)
  1350                 return cmdutil.changebranch(ui, repo, revs, label)
  1325 
  1351 
  1326             if not opts.get('force') and label in repo.branchmap():
  1352             if not opts.get(b'force') and label in repo.branchmap():
  1327                 if label not in [p.branch() for p in repo[None].parents()]:
  1353                 if label not in [p.branch() for p in repo[None].parents()]:
  1328                     raise error.Abort(
  1354                     raise error.Abort(
  1329                         _('a branch of the same name already' ' exists'),
  1355                         _(b'a branch of the same name already' b' exists'),
  1330                         # i18n: "it" refers to an existing branch
  1356                         # i18n: "it" refers to an existing branch
  1331                         hint=_("use 'hg update' to switch to it"),
  1357                         hint=_(b"use 'hg update' to switch to it"),
  1332                     )
  1358                     )
  1333 
  1359 
  1334             repo.dirstate.setbranch(label)
  1360             repo.dirstate.setbranch(label)
  1335             ui.status(_('marked working directory as branch %s\n') % label)
  1361             ui.status(_(b'marked working directory as branch %s\n') % label)
  1336 
  1362 
  1337             # find any open named branches aside from default
  1363             # find any open named branches aside from default
  1338             for n, h, t, c in repo.branchmap().iterbranches():
  1364             for n, h, t, c in repo.branchmap().iterbranches():
  1339                 if n != "default" and not c:
  1365                 if n != b"default" and not c:
  1340                     return 0
  1366                     return 0
  1341             ui.status(
  1367             ui.status(
  1342                 _(
  1368                 _(
  1343                     '(branches are permanent and global, '
  1369                     b'(branches are permanent and global, '
  1344                     'did you want a bookmark?)\n'
  1370                     b'did you want a bookmark?)\n'
  1345                 )
  1371                 )
  1346             )
  1372             )
  1347 
  1373 
  1348 
  1374 
  1349 @command(
  1375 @command(
  1350     'branches',
  1376     b'branches',
  1351     [
  1377     [
  1352         (
  1378         (
  1353             'a',
  1379             b'a',
  1354             'active',
  1380             b'active',
  1355             False,
  1381             False,
  1356             _('show only branches that have unmerged heads (DEPRECATED)'),
  1382             _(b'show only branches that have unmerged heads (DEPRECATED)'),
  1357         ),
  1383         ),
  1358         ('c', 'closed', False, _('show normal and closed branches')),
  1384         (b'c', b'closed', False, _(b'show normal and closed branches')),
  1359         ('r', 'rev', [], _('show branch name(s) of the given rev')),
  1385         (b'r', b'rev', [], _(b'show branch name(s) of the given rev')),
  1360     ]
  1386     ]
  1361     + formatteropts,
  1387     + formatteropts,
  1362     _('[-c]'),
  1388     _(b'[-c]'),
  1363     helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
  1389     helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
  1364     intents={INTENT_READONLY},
  1390     intents={INTENT_READONLY},
  1365 )
  1391 )
  1366 def branches(ui, repo, active=False, closed=False, **opts):
  1392 def branches(ui, repo, active=False, closed=False, **opts):
  1367     """list repository named branches
  1393     """list repository named branches
  1386 
  1412 
  1387     Returns 0.
  1413     Returns 0.
  1388     """
  1414     """
  1389 
  1415 
  1390     opts = pycompat.byteskwargs(opts)
  1416     opts = pycompat.byteskwargs(opts)
  1391     revs = opts.get('rev')
  1417     revs = opts.get(b'rev')
  1392     selectedbranches = None
  1418     selectedbranches = None
  1393     if revs:
  1419     if revs:
  1394         revs = scmutil.revrange(repo, revs)
  1420         revs = scmutil.revrange(repo, revs)
  1395         getbi = repo.revbranchcache().branchinfo
  1421         getbi = repo.revbranchcache().branchinfo
  1396         selectedbranches = {getbi(r)[0] for r in revs}
  1422         selectedbranches = {getbi(r)[0] for r in revs}
  1397 
  1423 
  1398     ui.pager('branches')
  1424     ui.pager(b'branches')
  1399     fm = ui.formatter('branches', opts)
  1425     fm = ui.formatter(b'branches', opts)
  1400     hexfunc = fm.hexfunc
  1426     hexfunc = fm.hexfunc
  1401 
  1427 
  1402     allheads = set(repo.heads())
  1428     allheads = set(repo.heads())
  1403     branches = []
  1429     branches = []
  1404     for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
  1430     for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
  1413 
  1439 
  1414     for tag, ctx, isactive, isopen in branches:
  1440     for tag, ctx, isactive, isopen in branches:
  1415         if active and not isactive:
  1441         if active and not isactive:
  1416             continue
  1442             continue
  1417         if isactive:
  1443         if isactive:
  1418             label = 'branches.active'
  1444             label = b'branches.active'
  1419             notice = ''
  1445             notice = b''
  1420         elif not isopen:
  1446         elif not isopen:
  1421             if not closed:
  1447             if not closed:
  1422                 continue
  1448                 continue
  1423             label = 'branches.closed'
  1449             label = b'branches.closed'
  1424             notice = _(' (closed)')
  1450             notice = _(b' (closed)')
  1425         else:
  1451         else:
  1426             label = 'branches.inactive'
  1452             label = b'branches.inactive'
  1427             notice = _(' (inactive)')
  1453             notice = _(b' (inactive)')
  1428         current = tag == repo.dirstate.branch()
  1454         current = tag == repo.dirstate.branch()
  1429         if current:
  1455         if current:
  1430             label = 'branches.current'
  1456             label = b'branches.current'
  1431 
  1457 
  1432         fm.startitem()
  1458         fm.startitem()
  1433         fm.write('branch', '%s', tag, label=label)
  1459         fm.write(b'branch', b'%s', tag, label=label)
  1434         rev = ctx.rev()
  1460         rev = ctx.rev()
  1435         padsize = max(31 - len("%d" % rev) - encoding.colwidth(tag), 0)
  1461         padsize = max(31 - len(b"%d" % rev) - encoding.colwidth(tag), 0)
  1436         fmt = ' ' * padsize + ' %d:%s'
  1462         fmt = b' ' * padsize + b' %d:%s'
  1437         fm.condwrite(
  1463         fm.condwrite(
  1438             not ui.quiet,
  1464             not ui.quiet,
  1439             'rev node',
  1465             b'rev node',
  1440             fmt,
  1466             fmt,
  1441             rev,
  1467             rev,
  1442             hexfunc(ctx.node()),
  1468             hexfunc(ctx.node()),
  1443             label='log.changeset changeset.%s' % ctx.phasestr(),
  1469             label=b'log.changeset changeset.%s' % ctx.phasestr(),
  1444         )
  1470         )
  1445         fm.context(ctx=ctx)
  1471         fm.context(ctx=ctx)
  1446         fm.data(active=isactive, closed=not isopen, current=current)
  1472         fm.data(active=isactive, closed=not isopen, current=current)
  1447         if not ui.quiet:
  1473         if not ui.quiet:
  1448             fm.plain(notice)
  1474             fm.plain(notice)
  1449         fm.plain('\n')
  1475         fm.plain(b'\n')
  1450     fm.end()
  1476     fm.end()
  1451 
  1477 
  1452 
  1478 
  1453 @command(
  1479 @command(
  1454     'bundle',
  1480     b'bundle',
  1455     [
  1481     [
  1456         ('f', 'force', None, _('run even when the destination is unrelated')),
  1482         (
  1457         (
  1483             b'f',
  1458             'r',
  1484             b'force',
  1459             'rev',
  1485             None,
       
  1486             _(b'run even when the destination is unrelated'),
       
  1487         ),
       
  1488         (
       
  1489             b'r',
       
  1490             b'rev',
  1460             [],
  1491             [],
  1461             _('a changeset intended to be added to the destination'),
  1492             _(b'a changeset intended to be added to the destination'),
  1462             _('REV'),
  1493             _(b'REV'),
  1463         ),
  1494         ),
  1464         (
  1495         (
  1465             'b',
  1496             b'b',
  1466             'branch',
  1497             b'branch',
  1467             [],
  1498             [],
  1468             _('a specific branch you would like to bundle'),
  1499             _(b'a specific branch you would like to bundle'),
  1469             _('BRANCH'),
  1500             _(b'BRANCH'),
  1470         ),
  1501         ),
  1471         (
  1502         (
  1472             '',
  1503             b'',
  1473             'base',
  1504             b'base',
  1474             [],
  1505             [],
  1475             _('a base changeset assumed to be available at the destination'),
  1506             _(b'a base changeset assumed to be available at the destination'),
  1476             _('REV'),
  1507             _(b'REV'),
  1477         ),
  1508         ),
  1478         ('a', 'all', None, _('bundle all changesets in the repository')),
  1509         (b'a', b'all', None, _(b'bundle all changesets in the repository')),
  1479         ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
  1510         (
       
  1511             b't',
       
  1512             b'type',
       
  1513             b'bzip2',
       
  1514             _(b'bundle compression type to use'),
       
  1515             _(b'TYPE'),
       
  1516         ),
  1480     ]
  1517     ]
  1481     + remoteopts,
  1518     + remoteopts,
  1482     _('[-f] [-t BUNDLESPEC] [-a] [-r REV]... [--base REV]... FILE [DEST]'),
  1519     _(b'[-f] [-t BUNDLESPEC] [-a] [-r REV]... [--base REV]... FILE [DEST]'),
  1483     helpcategory=command.CATEGORY_IMPORT_EXPORT,
  1520     helpcategory=command.CATEGORY_IMPORT_EXPORT,
  1484 )
  1521 )
  1485 def bundle(ui, repo, fname, dest=None, **opts):
  1522 def bundle(ui, repo, fname, dest=None, **opts):
  1486     """create a bundle file
  1523     """create a bundle file
  1487 
  1524 
  1510 
  1547 
  1511     Returns 0 on success, 1 if no changes found.
  1548     Returns 0 on success, 1 if no changes found.
  1512     """
  1549     """
  1513     opts = pycompat.byteskwargs(opts)
  1550     opts = pycompat.byteskwargs(opts)
  1514     revs = None
  1551     revs = None
  1515     if 'rev' in opts:
  1552     if b'rev' in opts:
  1516         revstrings = opts['rev']
  1553         revstrings = opts[b'rev']
  1517         revs = scmutil.revrange(repo, revstrings)
  1554         revs = scmutil.revrange(repo, revstrings)
  1518         if revstrings and not revs:
  1555         if revstrings and not revs:
  1519             raise error.Abort(_('no commits to bundle'))
  1556             raise error.Abort(_(b'no commits to bundle'))
  1520 
  1557 
  1521     bundletype = opts.get('type', 'bzip2').lower()
  1558     bundletype = opts.get(b'type', b'bzip2').lower()
  1522     try:
  1559     try:
  1523         bundlespec = exchange.parsebundlespec(repo, bundletype, strict=False)
  1560         bundlespec = exchange.parsebundlespec(repo, bundletype, strict=False)
  1524     except error.UnsupportedBundleSpecification as e:
  1561     except error.UnsupportedBundleSpecification as e:
  1525         raise error.Abort(
  1562         raise error.Abort(
  1526             pycompat.bytestr(e),
  1563             pycompat.bytestr(e),
  1527             hint=_(
  1564             hint=_(
  1528                 "see 'hg help bundlespec' for supported " "values for --type"
  1565                 b"see 'hg help bundlespec' for supported " b"values for --type"
  1529             ),
  1566             ),
  1530         )
  1567         )
  1531     cgversion = bundlespec.contentopts["cg.version"]
  1568     cgversion = bundlespec.contentopts[b"cg.version"]
  1532 
  1569 
  1533     # Packed bundles are a pseudo bundle format for now.
  1570     # Packed bundles are a pseudo bundle format for now.
  1534     if cgversion == 's1':
  1571     if cgversion == b's1':
  1535         raise error.Abort(
  1572         raise error.Abort(
  1536             _('packed bundles cannot be produced by "hg bundle"'),
  1573             _(b'packed bundles cannot be produced by "hg bundle"'),
  1537             hint=_("use 'hg debugcreatestreamclonebundle'"),
  1574             hint=_(b"use 'hg debugcreatestreamclonebundle'"),
  1538         )
  1575         )
  1539 
  1576 
  1540     if opts.get('all'):
  1577     if opts.get(b'all'):
  1541         if dest:
  1578         if dest:
  1542             raise error.Abort(
  1579             raise error.Abort(
  1543                 _("--all is incompatible with specifying " "a destination")
  1580                 _(b"--all is incompatible with specifying " b"a destination")
  1544             )
  1581             )
  1545         if opts.get('base'):
  1582         if opts.get(b'base'):
  1546             ui.warn(_("ignoring --base because --all was specified\n"))
  1583             ui.warn(_(b"ignoring --base because --all was specified\n"))
  1547         base = [nullrev]
  1584         base = [nullrev]
  1548     else:
  1585     else:
  1549         base = scmutil.revrange(repo, opts.get('base'))
  1586         base = scmutil.revrange(repo, opts.get(b'base'))
  1550     if cgversion not in changegroup.supportedoutgoingversions(repo):
  1587     if cgversion not in changegroup.supportedoutgoingversions(repo):
  1551         raise error.Abort(
  1588         raise error.Abort(
  1552             _("repository does not support bundle version %s") % cgversion
  1589             _(b"repository does not support bundle version %s") % cgversion
  1553         )
  1590         )
  1554 
  1591 
  1555     if base:
  1592     if base:
  1556         if dest:
  1593         if dest:
  1557             raise error.Abort(
  1594             raise error.Abort(
  1558                 _("--base is incompatible with specifying " "a destination")
  1595                 _(b"--base is incompatible with specifying " b"a destination")
  1559             )
  1596             )
  1560         common = [repo[rev].node() for rev in base]
  1597         common = [repo[rev].node() for rev in base]
  1561         heads = [repo[r].node() for r in revs] if revs else None
  1598         heads = [repo[r].node() for r in revs] if revs else None
  1562         outgoing = discovery.outgoing(repo, common, heads)
  1599         outgoing = discovery.outgoing(repo, common, heads)
  1563     else:
  1600     else:
  1564         dest = ui.expandpath(dest or 'default-push', dest or 'default')
  1601         dest = ui.expandpath(dest or b'default-push', dest or b'default')
  1565         dest, branches = hg.parseurl(dest, opts.get('branch'))
  1602         dest, branches = hg.parseurl(dest, opts.get(b'branch'))
  1566         other = hg.peer(repo, opts, dest)
  1603         other = hg.peer(repo, opts, dest)
  1567         revs = [repo[r].hex() for r in revs]
  1604         revs = [repo[r].hex() for r in revs]
  1568         revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
  1605         revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
  1569         heads = revs and pycompat.maplist(repo.lookup, revs) or revs
  1606         heads = revs and pycompat.maplist(repo.lookup, revs) or revs
  1570         outgoing = discovery.findcommonoutgoing(
  1607         outgoing = discovery.findcommonoutgoing(
  1571             repo, other, onlyheads=heads, force=opts.get('force'), portable=True
  1608             repo,
       
  1609             other,
       
  1610             onlyheads=heads,
       
  1611             force=opts.get(b'force'),
       
  1612             portable=True,
  1572         )
  1613         )
  1573 
  1614 
  1574     if not outgoing.missing:
  1615     if not outgoing.missing:
  1575         scmutil.nochangesfound(ui, repo, not base and outgoing.excluded)
  1616         scmutil.nochangesfound(ui, repo, not base and outgoing.excluded)
  1576         return 1
  1617         return 1
  1577 
  1618 
  1578     if cgversion == '01':  # bundle1
  1619     if cgversion == b'01':  # bundle1
  1579         bversion = 'HG10' + bundlespec.wirecompression
  1620         bversion = b'HG10' + bundlespec.wirecompression
  1580         bcompression = None
  1621         bcompression = None
  1581     elif cgversion in ('02', '03'):
  1622     elif cgversion in (b'02', b'03'):
  1582         bversion = 'HG20'
  1623         bversion = b'HG20'
  1583         bcompression = bundlespec.wirecompression
  1624         bcompression = bundlespec.wirecompression
  1584     else:
  1625     else:
  1585         raise error.ProgrammingError(
  1626         raise error.ProgrammingError(
  1586             'bundle: unexpected changegroup version %s' % cgversion
  1627             b'bundle: unexpected changegroup version %s' % cgversion
  1587         )
  1628         )
  1588 
  1629 
  1589     # TODO compression options should be derived from bundlespec parsing.
  1630     # TODO compression options should be derived from bundlespec parsing.
  1590     # This is a temporary hack to allow adjusting bundle compression
  1631     # This is a temporary hack to allow adjusting bundle compression
  1591     # level without a) formalizing the bundlespec changes to declare it
  1632     # level without a) formalizing the bundlespec changes to declare it
  1592     # b) introducing a command flag.
  1633     # b) introducing a command flag.
  1593     compopts = {}
  1634     compopts = {}
  1594     complevel = ui.configint(
  1635     complevel = ui.configint(
  1595         'experimental', 'bundlecomplevel.' + bundlespec.compression
  1636         b'experimental', b'bundlecomplevel.' + bundlespec.compression
  1596     )
  1637     )
  1597     if complevel is None:
  1638     if complevel is None:
  1598         complevel = ui.configint('experimental', 'bundlecomplevel')
  1639         complevel = ui.configint(b'experimental', b'bundlecomplevel')
  1599     if complevel is not None:
  1640     if complevel is not None:
  1600         compopts['level'] = complevel
  1641         compopts[b'level'] = complevel
  1601 
  1642 
  1602     # Allow overriding the bundling of obsmarker in phases through
  1643     # Allow overriding the bundling of obsmarker in phases through
  1603     # configuration while we don't have a bundle version that include them
  1644     # configuration while we don't have a bundle version that include them
  1604     if repo.ui.configbool('experimental', 'evolution.bundle-obsmarker'):
  1645     if repo.ui.configbool(b'experimental', b'evolution.bundle-obsmarker'):
  1605         bundlespec.contentopts['obsolescence'] = True
  1646         bundlespec.contentopts[b'obsolescence'] = True
  1606     if repo.ui.configbool('experimental', 'bundle-phases'):
  1647     if repo.ui.configbool(b'experimental', b'bundle-phases'):
  1607         bundlespec.contentopts['phases'] = True
  1648         bundlespec.contentopts[b'phases'] = True
  1608 
  1649 
  1609     bundle2.writenewbundle(
  1650     bundle2.writenewbundle(
  1610         ui,
  1651         ui,
  1611         repo,
  1652         repo,
  1612         'bundle',
  1653         b'bundle',
  1613         fname,
  1654         fname,
  1614         bversion,
  1655         bversion,
  1615         outgoing,
  1656         outgoing,
  1616         bundlespec.contentopts,
  1657         bundlespec.contentopts,
  1617         compression=bcompression,
  1658         compression=bcompression,
  1618         compopts=compopts,
  1659         compopts=compopts,
  1619     )
  1660     )
  1620 
  1661 
  1621 
  1662 
  1622 @command(
  1663 @command(
  1623     'cat',
  1664     b'cat',
  1624     [
  1665     [
  1625         (
  1666         (
  1626             'o',
  1667             b'o',
  1627             'output',
  1668             b'output',
  1628             '',
  1669             b'',
  1629             _('print output to file with formatted name'),
  1670             _(b'print output to file with formatted name'),
  1630             _('FORMAT'),
  1671             _(b'FORMAT'),
  1631         ),
  1672         ),
  1632         ('r', 'rev', '', _('print the given revision'), _('REV')),
  1673         (b'r', b'rev', b'', _(b'print the given revision'), _(b'REV')),
  1633         ('', 'decode', None, _('apply any matching decode filter')),
  1674         (b'', b'decode', None, _(b'apply any matching decode filter')),
  1634     ]
  1675     ]
  1635     + walkopts
  1676     + walkopts
  1636     + formatteropts,
  1677     + formatteropts,
  1637     _('[OPTION]... FILE...'),
  1678     _(b'[OPTION]... FILE...'),
  1638     helpcategory=command.CATEGORY_FILE_CONTENTS,
  1679     helpcategory=command.CATEGORY_FILE_CONTENTS,
  1639     inferrepo=True,
  1680     inferrepo=True,
  1640     intents={INTENT_READONLY},
  1681     intents={INTENT_READONLY},
  1641 )
  1682 )
  1642 def cat(ui, repo, file1, *pats, **opts):
  1683 def cat(ui, repo, file1, *pats, **opts):
  1672       :path:    String. Repository-absolute path of the file.
  1713       :path:    String. Repository-absolute path of the file.
  1673 
  1714 
  1674     Returns 0 on success.
  1715     Returns 0 on success.
  1675     """
  1716     """
  1676     opts = pycompat.byteskwargs(opts)
  1717     opts = pycompat.byteskwargs(opts)
  1677     rev = opts.get('rev')
  1718     rev = opts.get(b'rev')
  1678     if rev:
  1719     if rev:
  1679         repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
  1720         repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
  1680     ctx = scmutil.revsingle(repo, rev)
  1721     ctx = scmutil.revsingle(repo, rev)
  1681     m = scmutil.match(ctx, (file1,) + pats, opts)
  1722     m = scmutil.match(ctx, (file1,) + pats, opts)
  1682     fntemplate = opts.pop('output', '')
  1723     fntemplate = opts.pop(b'output', b'')
  1683     if cmdutil.isstdiofilename(fntemplate):
  1724     if cmdutil.isstdiofilename(fntemplate):
  1684         fntemplate = ''
  1725         fntemplate = b''
  1685 
  1726 
  1686     if fntemplate:
  1727     if fntemplate:
  1687         fm = formatter.nullformatter(ui, 'cat', opts)
  1728         fm = formatter.nullformatter(ui, b'cat', opts)
  1688     else:
  1729     else:
  1689         ui.pager('cat')
  1730         ui.pager(b'cat')
  1690         fm = ui.formatter('cat', opts)
  1731         fm = ui.formatter(b'cat', opts)
  1691     with fm:
  1732     with fm:
  1692         return cmdutil.cat(
  1733         return cmdutil.cat(
  1693             ui, repo, ctx, m, fm, fntemplate, '', **pycompat.strkwargs(opts)
  1734             ui, repo, ctx, m, fm, fntemplate, b'', **pycompat.strkwargs(opts)
  1694         )
  1735         )
  1695 
  1736 
  1696 
  1737 
  1697 @command(
  1738 @command(
  1698     'clone',
  1739     b'clone',
  1699     [
  1740     [
  1700         (
  1741         (
  1701             'U',
  1742             b'U',
  1702             'noupdate',
  1743             b'noupdate',
  1703             None,
  1744             None,
  1704             _(
  1745             _(
  1705                 'the clone will include an empty working '
  1746                 b'the clone will include an empty working '
  1706                 'directory (only a repository)'
  1747                 b'directory (only a repository)'
  1707             ),
  1748             ),
  1708         ),
  1749         ),
  1709         (
  1750         (
  1710             'u',
  1751             b'u',
  1711             'updaterev',
  1752             b'updaterev',
  1712             '',
  1753             b'',
  1713             _('revision, tag, or branch to check out'),
  1754             _(b'revision, tag, or branch to check out'),
  1714             _('REV'),
  1755             _(b'REV'),
  1715         ),
  1756         ),
  1716         (
  1757         (
  1717             'r',
  1758             b'r',
  1718             'rev',
  1759             b'rev',
  1719             [],
  1760             [],
  1720             _(
  1761             _(
  1721                 'do not clone everything, but include this changeset'
  1762                 b'do not clone everything, but include this changeset'
  1722                 ' and its ancestors'
  1763                 b' and its ancestors'
  1723             ),
  1764             ),
  1724             _('REV'),
  1765             _(b'REV'),
  1725         ),
  1766         ),
  1726         (
  1767         (
  1727             'b',
  1768             b'b',
  1728             'branch',
  1769             b'branch',
  1729             [],
  1770             [],
  1730             _(
  1771             _(
  1731                 'do not clone everything, but include this branch\'s'
  1772                 b'do not clone everything, but include this branch\'s'
  1732                 ' changesets and their ancestors'
  1773                 b' changesets and their ancestors'
  1733             ),
  1774             ),
  1734             _('BRANCH'),
  1775             _(b'BRANCH'),
  1735         ),
  1776         ),
  1736         ('', 'pull', None, _('use pull protocol to copy metadata')),
  1777         (b'', b'pull', None, _(b'use pull protocol to copy metadata')),
  1737         ('', 'uncompressed', None, _('an alias to --stream (DEPRECATED)')),
  1778         (b'', b'uncompressed', None, _(b'an alias to --stream (DEPRECATED)')),
  1738         ('', 'stream', None, _('clone with minimal data processing')),
  1779         (b'', b'stream', None, _(b'clone with minimal data processing')),
  1739     ]
  1780     ]
  1740     + remoteopts,
  1781     + remoteopts,
  1741     _('[OPTION]... SOURCE [DEST]'),
  1782     _(b'[OPTION]... SOURCE [DEST]'),
  1742     helpcategory=command.CATEGORY_REPO_CREATION,
  1783     helpcategory=command.CATEGORY_REPO_CREATION,
  1743     helpbasic=True,
  1784     helpbasic=True,
  1744     norepo=True,
  1785     norepo=True,
  1745 )
  1786 )
  1746 def clone(ui, source, dest=None, **opts):
  1787 def clone(ui, source, dest=None, **opts):
  1850     See :hg:`help urls` for details on specifying URLs.
  1891     See :hg:`help urls` for details on specifying URLs.
  1851 
  1892 
  1852     Returns 0 on success.
  1893     Returns 0 on success.
  1853     """
  1894     """
  1854     opts = pycompat.byteskwargs(opts)
  1895     opts = pycompat.byteskwargs(opts)
  1855     if opts.get('noupdate') and opts.get('updaterev'):
  1896     if opts.get(b'noupdate') and opts.get(b'updaterev'):
  1856         raise error.Abort(_("cannot specify both --noupdate and --updaterev"))
  1897         raise error.Abort(_(b"cannot specify both --noupdate and --updaterev"))
  1857 
  1898 
  1858     # --include/--exclude can come from narrow or sparse.
  1899     # --include/--exclude can come from narrow or sparse.
  1859     includepats, excludepats = None, None
  1900     includepats, excludepats = None, None
  1860 
  1901 
  1861     # hg.clone() differentiates between None and an empty set. So make sure
  1902     # hg.clone() differentiates between None and an empty set. So make sure
  1862     # patterns are sets if narrow is requested without patterns.
  1903     # patterns are sets if narrow is requested without patterns.
  1863     if opts.get('narrow'):
  1904     if opts.get(b'narrow'):
  1864         includepats = set()
  1905         includepats = set()
  1865         excludepats = set()
  1906         excludepats = set()
  1866 
  1907 
  1867         if opts.get('include'):
  1908         if opts.get(b'include'):
  1868             includepats = narrowspec.parsepatterns(opts.get('include'))
  1909             includepats = narrowspec.parsepatterns(opts.get(b'include'))
  1869         if opts.get('exclude'):
  1910         if opts.get(b'exclude'):
  1870             excludepats = narrowspec.parsepatterns(opts.get('exclude'))
  1911             excludepats = narrowspec.parsepatterns(opts.get(b'exclude'))
  1871 
  1912 
  1872     r = hg.clone(
  1913     r = hg.clone(
  1873         ui,
  1914         ui,
  1874         opts,
  1915         opts,
  1875         source,
  1916         source,
  1876         dest,
  1917         dest,
  1877         pull=opts.get('pull'),
  1918         pull=opts.get(b'pull'),
  1878         stream=opts.get('stream') or opts.get('uncompressed'),
  1919         stream=opts.get(b'stream') or opts.get(b'uncompressed'),
  1879         revs=opts.get('rev'),
  1920         revs=opts.get(b'rev'),
  1880         update=opts.get('updaterev') or not opts.get('noupdate'),
  1921         update=opts.get(b'updaterev') or not opts.get(b'noupdate'),
  1881         branch=opts.get('branch'),
  1922         branch=opts.get(b'branch'),
  1882         shareopts=opts.get('shareopts'),
  1923         shareopts=opts.get(b'shareopts'),
  1883         storeincludepats=includepats,
  1924         storeincludepats=includepats,
  1884         storeexcludepats=excludepats,
  1925         storeexcludepats=excludepats,
  1885         depth=opts.get('depth') or None,
  1926         depth=opts.get(b'depth') or None,
  1886     )
  1927     )
  1887 
  1928 
  1888     return r is None
  1929     return r is None
  1889 
  1930 
  1890 
  1931 
  1891 @command(
  1932 @command(
  1892     'commit|ci',
  1933     b'commit|ci',
  1893     [
  1934     [
  1894         (
  1935         (
  1895             'A',
  1936             b'A',
  1896             'addremove',
  1937             b'addremove',
  1897             None,
  1938             None,
  1898             _('mark new/missing files as added/removed before committing'),
  1939             _(b'mark new/missing files as added/removed before committing'),
  1899         ),
  1940         ),
  1900         ('', 'close-branch', None, _('mark a branch head as closed')),
  1941         (b'', b'close-branch', None, _(b'mark a branch head as closed')),
  1901         ('', 'amend', None, _('amend the parent of the working directory')),
  1942         (b'', b'amend', None, _(b'amend the parent of the working directory')),
  1902         ('s', 'secret', None, _('use the secret phase for committing')),
  1943         (b's', b'secret', None, _(b'use the secret phase for committing')),
  1903         ('e', 'edit', None, _('invoke editor on commit messages')),
  1944         (b'e', b'edit', None, _(b'invoke editor on commit messages')),
  1904         (
  1945         (
  1905             '',
  1946             b'',
  1906             'force-close-branch',
  1947             b'force-close-branch',
  1907             None,
  1948             None,
  1908             _('forcibly close branch from a non-head changeset (ADVANCED)'),
  1949             _(b'forcibly close branch from a non-head changeset (ADVANCED)'),
  1909         ),
  1950         ),
  1910         ('i', 'interactive', None, _('use interactive mode')),
  1951         (b'i', b'interactive', None, _(b'use interactive mode')),
  1911     ]
  1952     ]
  1912     + walkopts
  1953     + walkopts
  1913     + commitopts
  1954     + commitopts
  1914     + commitopts2
  1955     + commitopts2
  1915     + subrepoopts,
  1956     + subrepoopts,
  1916     _('[OPTION]... [FILE]...'),
  1957     _(b'[OPTION]... [FILE]...'),
  1917     helpcategory=command.CATEGORY_COMMITTING,
  1958     helpcategory=command.CATEGORY_COMMITTING,
  1918     helpbasic=True,
  1959     helpbasic=True,
  1919     inferrepo=True,
  1960     inferrepo=True,
  1920 )
  1961 )
  1921 def commit(ui, repo, *pats, **opts):
  1962 def commit(ui, repo, *pats, **opts):
  1987         # ret can be 0 (no changes to record) or the value returned by
  2028         # ret can be 0 (no changes to record) or the value returned by
  1988         # commit(), 1 if nothing changed or None on success.
  2029         # commit(), 1 if nothing changed or None on success.
  1989         return 1 if ret == 0 else ret
  2030         return 1 if ret == 0 else ret
  1990 
  2031 
  1991     opts = pycompat.byteskwargs(opts)
  2032     opts = pycompat.byteskwargs(opts)
  1992     if opts.get('subrepos'):
  2033     if opts.get(b'subrepos'):
  1993         if opts.get('amend'):
  2034         if opts.get(b'amend'):
  1994             raise error.Abort(_('cannot amend with --subrepos'))
  2035             raise error.Abort(_(b'cannot amend with --subrepos'))
  1995         # Let --subrepos on the command line override config setting.
  2036         # Let --subrepos on the command line override config setting.
  1996         ui.setconfig('ui', 'commitsubrepos', True, 'commit')
  2037         ui.setconfig(b'ui', b'commitsubrepos', True, b'commit')
  1997 
  2038 
  1998     cmdutil.checkunfinished(repo, commit=True)
  2039     cmdutil.checkunfinished(repo, commit=True)
  1999 
  2040 
  2000     branch = repo[None].branch()
  2041     branch = repo[None].branch()
  2001     bheads = repo.branchheads(branch)
  2042     bheads = repo.branchheads(branch)
  2002 
  2043 
  2003     extra = {}
  2044     extra = {}
  2004     if opts.get('close_branch') or opts.get('force_close_branch'):
  2045     if opts.get(b'close_branch') or opts.get(b'force_close_branch'):
  2005         extra['close'] = '1'
  2046         extra[b'close'] = b'1'
  2006 
  2047 
  2007         if repo['.'].closesbranch():
  2048         if repo[b'.'].closesbranch():
  2008             raise error.Abort(
  2049             raise error.Abort(
  2009                 _('current revision is already a branch closing' ' head')
  2050                 _(b'current revision is already a branch closing' b' head')
  2010             )
  2051             )
  2011         elif not bheads:
  2052         elif not bheads:
  2012             raise error.Abort(_('branch "%s" has no heads to close') % branch)
  2053             raise error.Abort(_(b'branch "%s" has no heads to close') % branch)
  2013         elif (
  2054         elif (
  2014             branch == repo['.'].branch()
  2055             branch == repo[b'.'].branch()
  2015             and repo['.'].node() not in bheads
  2056             and repo[b'.'].node() not in bheads
  2016             and not opts.get('force_close_branch')
  2057             and not opts.get(b'force_close_branch')
  2017         ):
  2058         ):
  2018             hint = _(
  2059             hint = _(
  2019                 'use --force-close-branch to close branch from a non-head'
  2060                 b'use --force-close-branch to close branch from a non-head'
  2020                 ' changeset'
  2061                 b' changeset'
  2021             )
  2062             )
  2022             raise error.Abort(_('can only close branch heads'), hint=hint)
  2063             raise error.Abort(_(b'can only close branch heads'), hint=hint)
  2023         elif opts.get('amend'):
  2064         elif opts.get(b'amend'):
  2024             if (
  2065             if (
  2025                 repo['.'].p1().branch() != branch
  2066                 repo[b'.'].p1().branch() != branch
  2026                 and repo['.'].p2().branch() != branch
  2067                 and repo[b'.'].p2().branch() != branch
  2027             ):
  2068             ):
  2028                 raise error.Abort(_('can only close branch heads'))
  2069                 raise error.Abort(_(b'can only close branch heads'))
  2029 
  2070 
  2030     if opts.get('amend'):
  2071     if opts.get(b'amend'):
  2031         if ui.configbool('ui', 'commitsubrepos'):
  2072         if ui.configbool(b'ui', b'commitsubrepos'):
  2032             raise error.Abort(_('cannot amend with ui.commitsubrepos enabled'))
  2073             raise error.Abort(_(b'cannot amend with ui.commitsubrepos enabled'))
  2033 
  2074 
  2034         old = repo['.']
  2075         old = repo[b'.']
  2035         rewriteutil.precheck(repo, [old.rev()], 'amend')
  2076         rewriteutil.precheck(repo, [old.rev()], b'amend')
  2036 
  2077 
  2037         # Currently histedit gets confused if an amend happens while histedit
  2078         # Currently histedit gets confused if an amend happens while histedit
  2038         # is in progress. Since we have a checkunfinished command, we are
  2079         # is in progress. Since we have a checkunfinished command, we are
  2039         # temporarily honoring it.
  2080         # temporarily honoring it.
  2040         #
  2081         #
  2043         if not obsolete.isenabled(repo, obsolete.createmarkersopt):
  2084         if not obsolete.isenabled(repo, obsolete.createmarkersopt):
  2044             cmdutil.checkunfinished(repo)
  2085             cmdutil.checkunfinished(repo)
  2045 
  2086 
  2046         node = cmdutil.amend(ui, repo, old, extra, pats, opts)
  2087         node = cmdutil.amend(ui, repo, old, extra, pats, opts)
  2047         if node == old.node():
  2088         if node == old.node():
  2048             ui.status(_("nothing changed\n"))
  2089             ui.status(_(b"nothing changed\n"))
  2049             return 1
  2090             return 1
  2050     else:
  2091     else:
  2051 
  2092 
  2052         def commitfunc(ui, repo, message, match, opts):
  2093         def commitfunc(ui, repo, message, match, opts):
  2053             overrides = {}
  2094             overrides = {}
  2054             if opts.get('secret'):
  2095             if opts.get(b'secret'):
  2055                 overrides[('phases', 'new-commit')] = 'secret'
  2096                 overrides[(b'phases', b'new-commit')] = b'secret'
  2056 
  2097 
  2057             baseui = repo.baseui
  2098             baseui = repo.baseui
  2058             with baseui.configoverride(overrides, 'commit'):
  2099             with baseui.configoverride(overrides, b'commit'):
  2059                 with ui.configoverride(overrides, 'commit'):
  2100                 with ui.configoverride(overrides, b'commit'):
  2060                     editform = cmdutil.mergeeditform(
  2101                     editform = cmdutil.mergeeditform(
  2061                         repo[None], 'commit.normal'
  2102                         repo[None], b'commit.normal'
  2062                     )
  2103                     )
  2063                     editor = cmdutil.getcommiteditor(
  2104                     editor = cmdutil.getcommiteditor(
  2064                         editform=editform, **pycompat.strkwargs(opts)
  2105                         editform=editform, **pycompat.strkwargs(opts)
  2065                     )
  2106                     )
  2066                     return repo.commit(
  2107                     return repo.commit(
  2067                         message,
  2108                         message,
  2068                         opts.get('user'),
  2109                         opts.get(b'user'),
  2069                         opts.get('date'),
  2110                         opts.get(b'date'),
  2070                         match,
  2111                         match,
  2071                         editor=editor,
  2112                         editor=editor,
  2072                         extra=extra,
  2113                         extra=extra,
  2073                     )
  2114                     )
  2074 
  2115 
  2077         if not node:
  2118         if not node:
  2078             stat = cmdutil.postcommitstatus(repo, pats, opts)
  2119             stat = cmdutil.postcommitstatus(repo, pats, opts)
  2079             if stat[3]:
  2120             if stat[3]:
  2080                 ui.status(
  2121                 ui.status(
  2081                     _(
  2122                     _(
  2082                         "nothing changed (%d missing files, see "
  2123                         b"nothing changed (%d missing files, see "
  2083                         "'hg status')\n"
  2124                         b"'hg status')\n"
  2084                     )
  2125                     )
  2085                     % len(stat[3])
  2126                     % len(stat[3])
  2086                 )
  2127                 )
  2087             else:
  2128             else:
  2088                 ui.status(_("nothing changed\n"))
  2129                 ui.status(_(b"nothing changed\n"))
  2089             return 1
  2130             return 1
  2090 
  2131 
  2091     cmdutil.commitstatus(repo, node, branch, bheads, opts)
  2132     cmdutil.commitstatus(repo, node, branch, bheads, opts)
  2092 
  2133 
  2093     if not ui.quiet and ui.configbool('commands', 'commit.post-status'):
  2134     if not ui.quiet and ui.configbool(b'commands', b'commit.post-status'):
  2094         status(
  2135         status(
  2095             ui,
  2136             ui,
  2096             repo,
  2137             repo,
  2097             modified=True,
  2138             modified=True,
  2098             added=True,
  2139             added=True,
  2099             removed=True,
  2140             removed=True,
  2100             deleted=True,
  2141             deleted=True,
  2101             unknown=True,
  2142             unknown=True,
  2102             subrepos=opts.get('subrepos'),
  2143             subrepos=opts.get(b'subrepos'),
  2103         )
  2144         )
  2104 
  2145 
  2105 
  2146 
  2106 @command(
  2147 @command(
  2107     'config|showconfig|debugconfig',
  2148     b'config|showconfig|debugconfig',
  2108     [
  2149     [
  2109         ('u', 'untrusted', None, _('show untrusted configuration options')),
  2150         (b'u', b'untrusted', None, _(b'show untrusted configuration options')),
  2110         ('e', 'edit', None, _('edit user config')),
  2151         (b'e', b'edit', None, _(b'edit user config')),
  2111         ('l', 'local', None, _('edit repository config')),
  2152         (b'l', b'local', None, _(b'edit repository config')),
  2112         ('g', 'global', None, _('edit global config')),
  2153         (b'g', b'global', None, _(b'edit global config')),
  2113     ]
  2154     ]
  2114     + formatteropts,
  2155     + formatteropts,
  2115     _('[-u] [NAME]...'),
  2156     _(b'[-u] [NAME]...'),
  2116     helpcategory=command.CATEGORY_HELP,
  2157     helpcategory=command.CATEGORY_HELP,
  2117     optionalrepo=True,
  2158     optionalrepo=True,
  2118     intents={INTENT_READONLY},
  2159     intents={INTENT_READONLY},
  2119 )
  2160 )
  2120 def config(ui, repo, *values, **opts):
  2161 def config(ui, repo, *values, **opts):
  2150     Returns 0 on success, 1 if NAME does not exist.
  2191     Returns 0 on success, 1 if NAME does not exist.
  2151 
  2192 
  2152     """
  2193     """
  2153 
  2194 
  2154     opts = pycompat.byteskwargs(opts)
  2195     opts = pycompat.byteskwargs(opts)
  2155     if opts.get('edit') or opts.get('local') or opts.get('global'):
  2196     if opts.get(b'edit') or opts.get(b'local') or opts.get(b'global'):
  2156         if opts.get('local') and opts.get('global'):
  2197         if opts.get(b'local') and opts.get(b'global'):
  2157             raise error.Abort(_("can't use --local and --global together"))
  2198             raise error.Abort(_(b"can't use --local and --global together"))
  2158 
  2199 
  2159         if opts.get('local'):
  2200         if opts.get(b'local'):
  2160             if not repo:
  2201             if not repo:
  2161                 raise error.Abort(_("can't use --local outside a repository"))
  2202                 raise error.Abort(_(b"can't use --local outside a repository"))
  2162             paths = [repo.vfs.join('hgrc')]
  2203             paths = [repo.vfs.join(b'hgrc')]
  2163         elif opts.get('global'):
  2204         elif opts.get(b'global'):
  2164             paths = rcutil.systemrcpath()
  2205             paths = rcutil.systemrcpath()
  2165         else:
  2206         else:
  2166             paths = rcutil.userrcpath()
  2207             paths = rcutil.userrcpath()
  2167 
  2208 
  2168         for f in paths:
  2209         for f in paths:
  2169             if os.path.exists(f):
  2210             if os.path.exists(f):
  2170                 break
  2211                 break
  2171         else:
  2212         else:
  2172             if opts.get('global'):
  2213             if opts.get(b'global'):
  2173                 samplehgrc = uimod.samplehgrcs['global']
  2214                 samplehgrc = uimod.samplehgrcs[b'global']
  2174             elif opts.get('local'):
  2215             elif opts.get(b'local'):
  2175                 samplehgrc = uimod.samplehgrcs['local']
  2216                 samplehgrc = uimod.samplehgrcs[b'local']
  2176             else:
  2217             else:
  2177                 samplehgrc = uimod.samplehgrcs['user']
  2218                 samplehgrc = uimod.samplehgrcs[b'user']
  2178 
  2219 
  2179             f = paths[0]
  2220             f = paths[0]
  2180             fp = open(f, "wb")
  2221             fp = open(f, b"wb")
  2181             fp.write(util.tonativeeol(samplehgrc))
  2222             fp.write(util.tonativeeol(samplehgrc))
  2182             fp.close()
  2223             fp.close()
  2183 
  2224 
  2184         editor = ui.geteditor()
  2225         editor = ui.geteditor()
  2185         ui.system(
  2226         ui.system(
  2186             "%s \"%s\"" % (editor, f),
  2227             b"%s \"%s\"" % (editor, f),
  2187             onerr=error.Abort,
  2228             onerr=error.Abort,
  2188             errprefix=_("edit failed"),
  2229             errprefix=_(b"edit failed"),
  2189             blockedtag='config_edit',
  2230             blockedtag=b'config_edit',
  2190         )
  2231         )
  2191         return
  2232         return
  2192     ui.pager('config')
  2233     ui.pager(b'config')
  2193     fm = ui.formatter('config', opts)
  2234     fm = ui.formatter(b'config', opts)
  2194     for t, f in rcutil.rccomponents():
  2235     for t, f in rcutil.rccomponents():
  2195         if t == 'path':
  2236         if t == b'path':
  2196             ui.debug('read config from: %s\n' % f)
  2237             ui.debug(b'read config from: %s\n' % f)
  2197         elif t == 'items':
  2238         elif t == b'items':
  2198             for section, name, value, source in f:
  2239             for section, name, value, source in f:
  2199                 ui.debug('set config by: %s\n' % source)
  2240                 ui.debug(b'set config by: %s\n' % source)
  2200         else:
  2241         else:
  2201             raise error.ProgrammingError('unknown rctype: %s' % t)
  2242             raise error.ProgrammingError(b'unknown rctype: %s' % t)
  2202     untrusted = bool(opts.get('untrusted'))
  2243     untrusted = bool(opts.get(b'untrusted'))
  2203 
  2244 
  2204     selsections = selentries = []
  2245     selsections = selentries = []
  2205     if values:
  2246     if values:
  2206         selsections = [v for v in values if '.' not in v]
  2247         selsections = [v for v in values if b'.' not in v]
  2207         selentries = [v for v in values if '.' in v]
  2248         selentries = [v for v in values if b'.' in v]
  2208     uniquesel = len(selentries) == 1 and not selsections
  2249     uniquesel = len(selentries) == 1 and not selsections
  2209     selsections = set(selsections)
  2250     selsections = set(selsections)
  2210     selentries = set(selentries)
  2251     selentries = set(selentries)
  2211 
  2252 
  2212     matched = False
  2253     matched = False
  2213     for section, name, value in ui.walkconfig(untrusted=untrusted):
  2254     for section, name, value in ui.walkconfig(untrusted=untrusted):
  2214         source = ui.configsource(section, name, untrusted)
  2255         source = ui.configsource(section, name, untrusted)
  2215         value = pycompat.bytestr(value)
  2256         value = pycompat.bytestr(value)
  2216         defaultvalue = ui.configdefault(section, name)
  2257         defaultvalue = ui.configdefault(section, name)
  2217         if fm.isplain():
  2258         if fm.isplain():
  2218             source = source or 'none'
  2259             source = source or b'none'
  2219             value = value.replace('\n', '\\n')
  2260             value = value.replace(b'\n', b'\\n')
  2220         entryname = section + '.' + name
  2261         entryname = section + b'.' + name
  2221         if values and not (section in selsections or entryname in selentries):
  2262         if values and not (section in selsections or entryname in selentries):
  2222             continue
  2263             continue
  2223         fm.startitem()
  2264         fm.startitem()
  2224         fm.condwrite(ui.debugflag, 'source', '%s: ', source)
  2265         fm.condwrite(ui.debugflag, b'source', b'%s: ', source)
  2225         if uniquesel:
  2266         if uniquesel:
  2226             fm.data(name=entryname)
  2267             fm.data(name=entryname)
  2227             fm.write('value', '%s\n', value)
  2268             fm.write(b'value', b'%s\n', value)
  2228         else:
  2269         else:
  2229             fm.write('name value', '%s=%s\n', entryname, value)
  2270             fm.write(b'name value', b'%s=%s\n', entryname, value)
  2230         fm.data(defaultvalue=defaultvalue)
  2271         fm.data(defaultvalue=defaultvalue)
  2231         matched = True
  2272         matched = True
  2232     fm.end()
  2273     fm.end()
  2233     if matched:
  2274     if matched:
  2234         return 0
  2275         return 0
  2235     return 1
  2276     return 1
  2236 
  2277 
  2237 
  2278 
  2238 @command(
  2279 @command(
  2239     'continue',
  2280     b'continue',
  2240     dryrunopts,
  2281     dryrunopts,
  2241     helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
  2282     helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
  2242     helpbasic=True,
  2283     helpbasic=True,
  2243 )
  2284 )
  2244 def continuecmd(ui, repo, **opts):
  2285 def continuecmd(ui, repo, **opts):
  2250     use --dry-run/-n to dry run the command.
  2291     use --dry-run/-n to dry run the command.
  2251     """
  2292     """
  2252     dryrun = opts.get(r'dry_run')
  2293     dryrun = opts.get(r'dry_run')
  2253     contstate = cmdutil.getunfinishedstate(repo)
  2294     contstate = cmdutil.getunfinishedstate(repo)
  2254     if not contstate:
  2295     if not contstate:
  2255         raise error.Abort(_('no operation in progress'))
  2296         raise error.Abort(_(b'no operation in progress'))
  2256     if not contstate.continuefunc:
  2297     if not contstate.continuefunc:
  2257         raise error.Abort(
  2298         raise error.Abort(
  2258             (
  2299             (
  2259                 _("%s in progress but does not support " "'hg continue'")
  2300                 _(b"%s in progress but does not support " b"'hg continue'")
  2260                 % (contstate._opname)
  2301                 % (contstate._opname)
  2261             ),
  2302             ),
  2262             hint=contstate.continuemsg(),
  2303             hint=contstate.continuemsg(),
  2263         )
  2304         )
  2264     if dryrun:
  2305     if dryrun:
  2265         ui.status(_('%s in progress, will be resumed\n') % (contstate._opname))
  2306         ui.status(_(b'%s in progress, will be resumed\n') % (contstate._opname))
  2266         return
  2307         return
  2267     return contstate.continuefunc(ui, repo)
  2308     return contstate.continuefunc(ui, repo)
  2268 
  2309 
  2269 
  2310 
  2270 @command(
  2311 @command(
  2271     'copy|cp',
  2312     b'copy|cp',
  2272     [
  2313     [
  2273         ('A', 'after', None, _('record a copy that has already occurred')),
  2314         (b'A', b'after', None, _(b'record a copy that has already occurred')),
  2274         ('f', 'force', None, _('forcibly copy over an existing managed file')),
  2315         (
       
  2316             b'f',
       
  2317             b'force',
       
  2318             None,
       
  2319             _(b'forcibly copy over an existing managed file'),
       
  2320         ),
  2275     ]
  2321     ]
  2276     + walkopts
  2322     + walkopts
  2277     + dryrunopts,
  2323     + dryrunopts,
  2278     _('[OPTION]... SOURCE... DEST'),
  2324     _(b'[OPTION]... SOURCE... DEST'),
  2279     helpcategory=command.CATEGORY_FILE_CONTENTS,
  2325     helpcategory=command.CATEGORY_FILE_CONTENTS,
  2280 )
  2326 )
  2281 def copy(ui, repo, *pats, **opts):
  2327 def copy(ui, repo, *pats, **opts):
  2282     """mark files as copied for the next commit
  2328     """mark files as copied for the next commit
  2283 
  2329 
  2298     with repo.wlock(False):
  2344     with repo.wlock(False):
  2299         return cmdutil.copy(ui, repo, pats, opts)
  2345         return cmdutil.copy(ui, repo, pats, opts)
  2300 
  2346 
  2301 
  2347 
  2302 @command(
  2348 @command(
  2303     'debugcommands',
  2349     b'debugcommands',
  2304     [],
  2350     [],
  2305     _('[COMMAND]'),
  2351     _(b'[COMMAND]'),
  2306     helpcategory=command.CATEGORY_HELP,
  2352     helpcategory=command.CATEGORY_HELP,
  2307     norepo=True,
  2353     norepo=True,
  2308 )
  2354 )
  2309 def debugcommands(ui, cmd='', *args):
  2355 def debugcommands(ui, cmd=b'', *args):
  2310     """list all available commands and options"""
  2356     """list all available commands and options"""
  2311     for cmd, vals in sorted(table.iteritems()):
  2357     for cmd, vals in sorted(table.iteritems()):
  2312         cmd = cmd.split('|')[0]
  2358         cmd = cmd.split(b'|')[0]
  2313         opts = ', '.join([i[1] for i in vals[1]])
  2359         opts = b', '.join([i[1] for i in vals[1]])
  2314         ui.write('%s: %s\n' % (cmd, opts))
  2360         ui.write(b'%s: %s\n' % (cmd, opts))
  2315 
  2361 
  2316 
  2362 
  2317 @command(
  2363 @command(
  2318     'debugcomplete',
  2364     b'debugcomplete',
  2319     [('o', 'options', None, _('show the command options'))],
  2365     [(b'o', b'options', None, _(b'show the command options'))],
  2320     _('[-o] CMD'),
  2366     _(b'[-o] CMD'),
  2321     helpcategory=command.CATEGORY_HELP,
  2367     helpcategory=command.CATEGORY_HELP,
  2322     norepo=True,
  2368     norepo=True,
  2323 )
  2369 )
  2324 def debugcomplete(ui, cmd='', **opts):
  2370 def debugcomplete(ui, cmd=b'', **opts):
  2325     """returns the completion list associated with the given command"""
  2371     """returns the completion list associated with the given command"""
  2326 
  2372 
  2327     if opts.get(r'options'):
  2373     if opts.get(r'options'):
  2328         options = []
  2374         options = []
  2329         otables = [globalopts]
  2375         otables = [globalopts]
  2330         if cmd:
  2376         if cmd:
  2331             aliases, entry = cmdutil.findcmd(cmd, table, False)
  2377             aliases, entry = cmdutil.findcmd(cmd, table, False)
  2332             otables.append(entry[1])
  2378             otables.append(entry[1])
  2333         for t in otables:
  2379         for t in otables:
  2334             for o in t:
  2380             for o in t:
  2335                 if "(DEPRECATED)" in o[3]:
  2381                 if b"(DEPRECATED)" in o[3]:
  2336                     continue
  2382                     continue
  2337                 if o[0]:
  2383                 if o[0]:
  2338                     options.append('-%s' % o[0])
  2384                     options.append(b'-%s' % o[0])
  2339                 options.append('--%s' % o[1])
  2385                 options.append(b'--%s' % o[1])
  2340         ui.write("%s\n" % "\n".join(options))
  2386         ui.write(b"%s\n" % b"\n".join(options))
  2341         return
  2387         return
  2342 
  2388 
  2343     cmdlist, unused_allcmds = cmdutil.findpossible(cmd, table)
  2389     cmdlist, unused_allcmds = cmdutil.findpossible(cmd, table)
  2344     if ui.verbose:
  2390     if ui.verbose:
  2345         cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
  2391         cmdlist = [b' '.join(c[0]) for c in cmdlist.values()]
  2346     ui.write("%s\n" % "\n".join(sorted(cmdlist)))
  2392     ui.write(b"%s\n" % b"\n".join(sorted(cmdlist)))
  2347 
  2393 
  2348 
  2394 
  2349 @command(
  2395 @command(
  2350     'diff',
  2396     b'diff',
  2351     [
  2397     [
  2352         ('r', 'rev', [], _('revision'), _('REV')),
  2398         (b'r', b'rev', [], _(b'revision'), _(b'REV')),
  2353         ('c', 'change', '', _('change made by revision'), _('REV')),
  2399         (b'c', b'change', b'', _(b'change made by revision'), _(b'REV')),
  2354     ]
  2400     ]
  2355     + diffopts
  2401     + diffopts
  2356     + diffopts2
  2402     + diffopts2
  2357     + walkopts
  2403     + walkopts
  2358     + subrepoopts,
  2404     + subrepoopts,
  2359     _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'),
  2405     _(b'[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'),
  2360     helpcategory=command.CATEGORY_FILE_CONTENTS,
  2406     helpcategory=command.CATEGORY_FILE_CONTENTS,
  2361     helpbasic=True,
  2407     helpbasic=True,
  2362     inferrepo=True,
  2408     inferrepo=True,
  2363     intents={INTENT_READONLY},
  2409     intents={INTENT_READONLY},
  2364 )
  2410 )
  2419 
  2465 
  2420     Returns 0 on success.
  2466     Returns 0 on success.
  2421     """
  2467     """
  2422 
  2468 
  2423     opts = pycompat.byteskwargs(opts)
  2469     opts = pycompat.byteskwargs(opts)
  2424     revs = opts.get('rev')
  2470     revs = opts.get(b'rev')
  2425     change = opts.get('change')
  2471     change = opts.get(b'change')
  2426     stat = opts.get('stat')
  2472     stat = opts.get(b'stat')
  2427     reverse = opts.get('reverse')
  2473     reverse = opts.get(b'reverse')
  2428 
  2474 
  2429     if revs and change:
  2475     if revs and change:
  2430         msg = _('cannot specify --rev and --change at the same time')
  2476         msg = _(b'cannot specify --rev and --change at the same time')
  2431         raise error.Abort(msg)
  2477         raise error.Abort(msg)
  2432     elif change:
  2478     elif change:
  2433         repo = scmutil.unhidehashlikerevs(repo, [change], 'nowarn')
  2479         repo = scmutil.unhidehashlikerevs(repo, [change], b'nowarn')
  2434         ctx2 = scmutil.revsingle(repo, change, None)
  2480         ctx2 = scmutil.revsingle(repo, change, None)
  2435         ctx1 = ctx2.p1()
  2481         ctx1 = ctx2.p1()
  2436     else:
  2482     else:
  2437         repo = scmutil.unhidehashlikerevs(repo, revs, 'nowarn')
  2483         repo = scmutil.unhidehashlikerevs(repo, revs, b'nowarn')
  2438         ctx1, ctx2 = scmutil.revpair(repo, revs)
  2484         ctx1, ctx2 = scmutil.revpair(repo, revs)
  2439     node1, node2 = ctx1.node(), ctx2.node()
  2485     node1, node2 = ctx1.node(), ctx2.node()
  2440 
  2486 
  2441     if reverse:
  2487     if reverse:
  2442         node1, node2 = node2, node1
  2488         node1, node2 = node2, node1
  2443 
  2489 
  2444     diffopts = patch.diffallopts(ui, opts)
  2490     diffopts = patch.diffallopts(ui, opts)
  2445     m = scmutil.match(ctx2, pats, opts)
  2491     m = scmutil.match(ctx2, pats, opts)
  2446     m = repo.narrowmatch(m)
  2492     m = repo.narrowmatch(m)
  2447     ui.pager('diff')
  2493     ui.pager(b'diff')
  2448     logcmdutil.diffordiffstat(
  2494     logcmdutil.diffordiffstat(
  2449         ui,
  2495         ui,
  2450         repo,
  2496         repo,
  2451         diffopts,
  2497         diffopts,
  2452         node1,
  2498         node1,
  2453         node2,
  2499         node2,
  2454         m,
  2500         m,
  2455         stat=stat,
  2501         stat=stat,
  2456         listsubrepos=opts.get('subrepos'),
  2502         listsubrepos=opts.get(b'subrepos'),
  2457         root=opts.get('root'),
  2503         root=opts.get(b'root'),
  2458     )
  2504     )
  2459 
  2505 
  2460 
  2506 
  2461 @command(
  2507 @command(
  2462     'export',
  2508     b'export',
  2463     [
  2509     [
  2464         (
  2510         (
  2465             'B',
  2511             b'B',
  2466             'bookmark',
  2512             b'bookmark',
  2467             '',
  2513             b'',
  2468             _('export changes only reachable by given bookmark'),
  2514             _(b'export changes only reachable by given bookmark'),
  2469             _('BOOKMARK'),
  2515             _(b'BOOKMARK'),
  2470         ),
  2516         ),
  2471         (
  2517         (
  2472             'o',
  2518             b'o',
  2473             'output',
  2519             b'output',
  2474             '',
  2520             b'',
  2475             _('print output to file with formatted name'),
  2521             _(b'print output to file with formatted name'),
  2476             _('FORMAT'),
  2522             _(b'FORMAT'),
  2477         ),
  2523         ),
  2478         ('', 'switch-parent', None, _('diff against the second parent')),
  2524         (b'', b'switch-parent', None, _(b'diff against the second parent')),
  2479         ('r', 'rev', [], _('revisions to export'), _('REV')),
  2525         (b'r', b'rev', [], _(b'revisions to export'), _(b'REV')),
  2480     ]
  2526     ]
  2481     + diffopts
  2527     + diffopts
  2482     + formatteropts,
  2528     + formatteropts,
  2483     _('[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'),
  2529     _(b'[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'),
  2484     helpcategory=command.CATEGORY_IMPORT_EXPORT,
  2530     helpcategory=command.CATEGORY_IMPORT_EXPORT,
  2485     helpbasic=True,
  2531     helpbasic=True,
  2486     intents={INTENT_READONLY},
  2532     intents={INTENT_READONLY},
  2487 )
  2533 )
  2488 def export(ui, repo, *changesets, **opts):
  2534 def export(ui, repo, *changesets, **opts):
  2558           hg export -r "outgoing()" -o "%n-%m.patch"
  2604           hg export -r "outgoing()" -o "%n-%m.patch"
  2559 
  2605 
  2560     Returns 0 on success.
  2606     Returns 0 on success.
  2561     """
  2607     """
  2562     opts = pycompat.byteskwargs(opts)
  2608     opts = pycompat.byteskwargs(opts)
  2563     bookmark = opts.get('bookmark')
  2609     bookmark = opts.get(b'bookmark')
  2564     changesets += tuple(opts.get('rev', []))
  2610     changesets += tuple(opts.get(b'rev', []))
  2565 
  2611 
  2566     if bookmark and changesets:
  2612     if bookmark and changesets:
  2567         raise error.Abort(_("-r and -B are mutually exclusive"))
  2613         raise error.Abort(_(b"-r and -B are mutually exclusive"))
  2568 
  2614 
  2569     if bookmark:
  2615     if bookmark:
  2570         if bookmark not in repo._bookmarks:
  2616         if bookmark not in repo._bookmarks:
  2571             raise error.Abort(_("bookmark '%s' not found") % bookmark)
  2617             raise error.Abort(_(b"bookmark '%s' not found") % bookmark)
  2572 
  2618 
  2573         revs = scmutil.bookmarkrevs(repo, bookmark)
  2619         revs = scmutil.bookmarkrevs(repo, bookmark)
  2574     else:
  2620     else:
  2575         if not changesets:
  2621         if not changesets:
  2576             changesets = ['.']
  2622             changesets = [b'.']
  2577 
  2623 
  2578         repo = scmutil.unhidehashlikerevs(repo, changesets, 'nowarn')
  2624         repo = scmutil.unhidehashlikerevs(repo, changesets, b'nowarn')
  2579         revs = scmutil.revrange(repo, changesets)
  2625         revs = scmutil.revrange(repo, changesets)
  2580 
  2626 
  2581     if not revs:
  2627     if not revs:
  2582         raise error.Abort(_("export requires at least one changeset"))
  2628         raise error.Abort(_(b"export requires at least one changeset"))
  2583     if len(revs) > 1:
  2629     if len(revs) > 1:
  2584         ui.note(_('exporting patches:\n'))
  2630         ui.note(_(b'exporting patches:\n'))
  2585     else:
  2631     else:
  2586         ui.note(_('exporting patch:\n'))
  2632         ui.note(_(b'exporting patch:\n'))
  2587 
  2633 
  2588     fntemplate = opts.get('output')
  2634     fntemplate = opts.get(b'output')
  2589     if cmdutil.isstdiofilename(fntemplate):
  2635     if cmdutil.isstdiofilename(fntemplate):
  2590         fntemplate = ''
  2636         fntemplate = b''
  2591 
  2637 
  2592     if fntemplate:
  2638     if fntemplate:
  2593         fm = formatter.nullformatter(ui, 'export', opts)
  2639         fm = formatter.nullformatter(ui, b'export', opts)
  2594     else:
  2640     else:
  2595         ui.pager('export')
  2641         ui.pager(b'export')
  2596         fm = ui.formatter('export', opts)
  2642         fm = ui.formatter(b'export', opts)
  2597     with fm:
  2643     with fm:
  2598         cmdutil.export(
  2644         cmdutil.export(
  2599             repo,
  2645             repo,
  2600             revs,
  2646             revs,
  2601             fm,
  2647             fm,
  2602             fntemplate=fntemplate,
  2648             fntemplate=fntemplate,
  2603             switch_parent=opts.get('switch_parent'),
  2649             switch_parent=opts.get(b'switch_parent'),
  2604             opts=patch.diffallopts(ui, opts),
  2650             opts=patch.diffallopts(ui, opts),
  2605         )
  2651         )
  2606 
  2652 
  2607 
  2653 
  2608 @command(
  2654 @command(
  2609     'files',
  2655     b'files',
  2610     [
  2656     [
  2611         ('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
  2657         (
  2612         ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
  2658             b'r',
       
  2659             b'rev',
       
  2660             b'',
       
  2661             _(b'search the repository as it is in REV'),
       
  2662             _(b'REV'),
       
  2663         ),
       
  2664         (
       
  2665             b'0',
       
  2666             b'print0',
       
  2667             None,
       
  2668             _(b'end filenames with NUL, for use with xargs'),
       
  2669         ),
  2613     ]
  2670     ]
  2614     + walkopts
  2671     + walkopts
  2615     + formatteropts
  2672     + formatteropts
  2616     + subrepoopts,
  2673     + subrepoopts,
  2617     _('[OPTION]... [FILE]...'),
  2674     _(b'[OPTION]... [FILE]...'),
  2618     helpcategory=command.CATEGORY_WORKING_DIRECTORY,
  2675     helpcategory=command.CATEGORY_WORKING_DIRECTORY,
  2619     intents={INTENT_READONLY},
  2676     intents={INTENT_READONLY},
  2620 )
  2677 )
  2621 def files(ui, repo, *pats, **opts):
  2678 def files(ui, repo, *pats, **opts):
  2622     """list tracked files
  2679     """list tracked files
  2671     Returns 0 if a match is found, 1 otherwise.
  2728     Returns 0 if a match is found, 1 otherwise.
  2672 
  2729 
  2673     """
  2730     """
  2674 
  2731 
  2675     opts = pycompat.byteskwargs(opts)
  2732     opts = pycompat.byteskwargs(opts)
  2676     rev = opts.get('rev')
  2733     rev = opts.get(b'rev')
  2677     if rev:
  2734     if rev:
  2678         repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
  2735         repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
  2679     ctx = scmutil.revsingle(repo, rev, None)
  2736     ctx = scmutil.revsingle(repo, rev, None)
  2680 
  2737 
  2681     end = '\n'
  2738     end = b'\n'
  2682     if opts.get('print0'):
  2739     if opts.get(b'print0'):
  2683         end = '\0'
  2740         end = b'\0'
  2684     fmt = '%s' + end
  2741     fmt = b'%s' + end
  2685 
  2742 
  2686     m = scmutil.match(ctx, pats, opts)
  2743     m = scmutil.match(ctx, pats, opts)
  2687     ui.pager('files')
  2744     ui.pager(b'files')
  2688     uipathfn = scmutil.getuipathfn(ctx.repo(), legacyrelativevalue=True)
  2745     uipathfn = scmutil.getuipathfn(ctx.repo(), legacyrelativevalue=True)
  2689     with ui.formatter('files', opts) as fm:
  2746     with ui.formatter(b'files', opts) as fm:
  2690         return cmdutil.files(
  2747         return cmdutil.files(
  2691             ui, ctx, m, uipathfn, fm, fmt, opts.get('subrepos')
  2748             ui, ctx, m, uipathfn, fm, fmt, opts.get(b'subrepos')
  2692         )
  2749         )
  2693 
  2750 
  2694 
  2751 
  2695 @command(
  2752 @command(
  2696     'forget',
  2753     b'forget',
  2697     [('i', 'interactive', None, _('use interactive mode')),]
  2754     [(b'i', b'interactive', None, _(b'use interactive mode')),]
  2698     + walkopts
  2755     + walkopts
  2699     + dryrunopts,
  2756     + dryrunopts,
  2700     _('[OPTION]... FILE...'),
  2757     _(b'[OPTION]... FILE...'),
  2701     helpcategory=command.CATEGORY_WORKING_DIRECTORY,
  2758     helpcategory=command.CATEGORY_WORKING_DIRECTORY,
  2702     helpbasic=True,
  2759     helpbasic=True,
  2703     inferrepo=True,
  2760     inferrepo=True,
  2704 )
  2761 )
  2705 def forget(ui, repo, *pats, **opts):
  2762 def forget(ui, repo, *pats, **opts):
  2731     Returns 0 on success.
  2788     Returns 0 on success.
  2732     """
  2789     """
  2733 
  2790 
  2734     opts = pycompat.byteskwargs(opts)
  2791     opts = pycompat.byteskwargs(opts)
  2735     if not pats:
  2792     if not pats:
  2736         raise error.Abort(_('no files specified'))
  2793         raise error.Abort(_(b'no files specified'))
  2737 
  2794 
  2738     m = scmutil.match(repo[None], pats, opts)
  2795     m = scmutil.match(repo[None], pats, opts)
  2739     dryrun, interactive = opts.get('dry_run'), opts.get('interactive')
  2796     dryrun, interactive = opts.get(b'dry_run'), opts.get(b'interactive')
  2740     uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
  2797     uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
  2741     rejected = cmdutil.forget(
  2798     rejected = cmdutil.forget(
  2742         ui,
  2799         ui,
  2743         repo,
  2800         repo,
  2744         m,
  2801         m,
  2745         prefix="",
  2802         prefix=b"",
  2746         uipathfn=uipathfn,
  2803         uipathfn=uipathfn,
  2747         explicitonly=False,
  2804         explicitonly=False,
  2748         dryrun=dryrun,
  2805         dryrun=dryrun,
  2749         interactive=interactive,
  2806         interactive=interactive,
  2750     )[0]
  2807     )[0]
  2751     return rejected and 1 or 0
  2808     return rejected and 1 or 0
  2752 
  2809 
  2753 
  2810 
  2754 @command(
  2811 @command(
  2755     'graft',
  2812     b'graft',
  2756     [
  2813     [
  2757         ('r', 'rev', [], _('revisions to graft'), _('REV')),
  2814         (b'r', b'rev', [], _(b'revisions to graft'), _(b'REV')),
  2758         (
  2815         (
  2759             '',
  2816             b'',
  2760             'base',
  2817             b'base',
  2761             '',
  2818             b'',
  2762             _('base revision when doing the graft merge (ADVANCED)'),
  2819             _(b'base revision when doing the graft merge (ADVANCED)'),
  2763             _('REV'),
  2820             _(b'REV'),
  2764         ),
  2821         ),
  2765         ('c', 'continue', False, _('resume interrupted graft')),
  2822         (b'c', b'continue', False, _(b'resume interrupted graft')),
  2766         ('', 'stop', False, _('stop interrupted graft')),
  2823         (b'', b'stop', False, _(b'stop interrupted graft')),
  2767         ('', 'abort', False, _('abort interrupted graft')),
  2824         (b'', b'abort', False, _(b'abort interrupted graft')),
  2768         ('e', 'edit', False, _('invoke editor on commit messages')),
  2825         (b'e', b'edit', False, _(b'invoke editor on commit messages')),
  2769         ('', 'log', None, _('append graft info to log message')),
  2826         (b'', b'log', None, _(b'append graft info to log message')),
  2770         (
  2827         (
  2771             '',
  2828             b'',
  2772             'no-commit',
  2829             b'no-commit',
  2773             None,
  2830             None,
  2774             _("don't commit, just apply the changes in working directory"),
  2831             _(b"don't commit, just apply the changes in working directory"),
  2775         ),
  2832         ),
  2776         ('f', 'force', False, _('force graft')),
  2833         (b'f', b'force', False, _(b'force graft')),
  2777         (
  2834         (
  2778             'D',
  2835             b'D',
  2779             'currentdate',
  2836             b'currentdate',
  2780             False,
  2837             False,
  2781             _('record the current date as commit date'),
  2838             _(b'record the current date as commit date'),
  2782         ),
  2839         ),
  2783         ('U', 'currentuser', False, _('record the current user as committer')),
  2840         (
       
  2841             b'U',
       
  2842             b'currentuser',
       
  2843             False,
       
  2844             _(b'record the current user as committer'),
       
  2845         ),
  2784     ]
  2846     ]
  2785     + commitopts2
  2847     + commitopts2
  2786     + mergetoolopts
  2848     + mergetoolopts
  2787     + dryrunopts,
  2849     + dryrunopts,
  2788     _('[OPTION]... [-r REV]... REV...'),
  2850     _(b'[OPTION]... [-r REV]... REV...'),
  2789     helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
  2851     helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
  2790 )
  2852 )
  2791 def graft(ui, repo, *revs, **opts):
  2853 def graft(ui, repo, *revs, **opts):
  2792     '''copy changes from other branches onto the current branch
  2854     '''copy changes from other branches onto the current branch
  2793 
  2855 
  2887         return _dograft(ui, repo, *revs, **opts)
  2949         return _dograft(ui, repo, *revs, **opts)
  2888 
  2950 
  2889 
  2951 
  2890 def _dograft(ui, repo, *revs, **opts):
  2952 def _dograft(ui, repo, *revs, **opts):
  2891     opts = pycompat.byteskwargs(opts)
  2953     opts = pycompat.byteskwargs(opts)
  2892     if revs and opts.get('rev'):
  2954     if revs and opts.get(b'rev'):
  2893         ui.warn(
  2955         ui.warn(
  2894             _(
  2956             _(
  2895                 'warning: inconsistent use of --rev might give unexpected '
  2957                 b'warning: inconsistent use of --rev might give unexpected '
  2896                 'revision ordering!\n'
  2958                 b'revision ordering!\n'
  2897             )
  2959             )
  2898         )
  2960         )
  2899 
  2961 
  2900     revs = list(revs)
  2962     revs = list(revs)
  2901     revs.extend(opts.get('rev'))
  2963     revs.extend(opts.get(b'rev'))
  2902     basectx = None
  2964     basectx = None
  2903     if opts.get('base'):
  2965     if opts.get(b'base'):
  2904         basectx = scmutil.revsingle(repo, opts['base'], None)
  2966         basectx = scmutil.revsingle(repo, opts[b'base'], None)
  2905     # a dict of data to be stored in state file
  2967     # a dict of data to be stored in state file
  2906     statedata = {}
  2968     statedata = {}
  2907     # list of new nodes created by ongoing graft
  2969     # list of new nodes created by ongoing graft
  2908     statedata['newnodes'] = []
  2970     statedata[b'newnodes'] = []
  2909 
  2971 
  2910     if opts.get('user') and opts.get('currentuser'):
  2972     if opts.get(b'user') and opts.get(b'currentuser'):
  2911         raise error.Abort(_('--user and --currentuser are mutually exclusive'))
  2973         raise error.Abort(_(b'--user and --currentuser are mutually exclusive'))
  2912     if opts.get('date') and opts.get('currentdate'):
  2974     if opts.get(b'date') and opts.get(b'currentdate'):
  2913         raise error.Abort(_('--date and --currentdate are mutually exclusive'))
  2975         raise error.Abort(_(b'--date and --currentdate are mutually exclusive'))
  2914     if not opts.get('user') and opts.get('currentuser'):
  2976     if not opts.get(b'user') and opts.get(b'currentuser'):
  2915         opts['user'] = ui.username()
  2977         opts[b'user'] = ui.username()
  2916     if not opts.get('date') and opts.get('currentdate'):
  2978     if not opts.get(b'date') and opts.get(b'currentdate'):
  2917         opts['date'] = "%d %d" % dateutil.makedate()
  2979         opts[b'date'] = b"%d %d" % dateutil.makedate()
  2918 
  2980 
  2919     editor = cmdutil.getcommiteditor(
  2981     editor = cmdutil.getcommiteditor(
  2920         editform='graft', **pycompat.strkwargs(opts)
  2982         editform=b'graft', **pycompat.strkwargs(opts)
  2921     )
  2983     )
  2922 
  2984 
  2923     cont = False
  2985     cont = False
  2924     if opts.get('no_commit'):
  2986     if opts.get(b'no_commit'):
  2925         if opts.get('edit'):
  2987         if opts.get(b'edit'):
  2926             raise error.Abort(
  2988             raise error.Abort(
  2927                 _("cannot specify --no-commit and " "--edit together")
  2989                 _(b"cannot specify --no-commit and " b"--edit together")
  2928             )
  2990             )
  2929         if opts.get('currentuser'):
  2991         if opts.get(b'currentuser'):
  2930             raise error.Abort(
  2992             raise error.Abort(
  2931                 _("cannot specify --no-commit and " "--currentuser together")
  2993                 _(b"cannot specify --no-commit and " b"--currentuser together")
  2932             )
  2994             )
  2933         if opts.get('currentdate'):
  2995         if opts.get(b'currentdate'):
  2934             raise error.Abort(
  2996             raise error.Abort(
  2935                 _("cannot specify --no-commit and " "--currentdate together")
  2997                 _(b"cannot specify --no-commit and " b"--currentdate together")
  2936             )
  2998             )
  2937         if opts.get('log'):
  2999         if opts.get(b'log'):
  2938             raise error.Abort(
  3000             raise error.Abort(
  2939                 _("cannot specify --no-commit and " "--log together")
  3001                 _(b"cannot specify --no-commit and " b"--log together")
  2940             )
  3002             )
  2941 
  3003 
  2942     graftstate = statemod.cmdstate(repo, 'graftstate')
  3004     graftstate = statemod.cmdstate(repo, b'graftstate')
  2943 
  3005 
  2944     if opts.get('stop'):
  3006     if opts.get(b'stop'):
  2945         if opts.get('continue'):
  3007         if opts.get(b'continue'):
  2946             raise error.Abort(
  3008             raise error.Abort(
  2947                 _("cannot use '--continue' and " "'--stop' together")
  3009                 _(b"cannot use '--continue' and " b"'--stop' together")
  2948             )
  3010             )
  2949         if opts.get('abort'):
  3011         if opts.get(b'abort'):
  2950             raise error.Abort(_("cannot use '--abort' and '--stop' together"))
  3012             raise error.Abort(_(b"cannot use '--abort' and '--stop' together"))
  2951 
  3013 
  2952         if any(
  3014         if any(
  2953             (
  3015             (
  2954                 opts.get('edit'),
  3016                 opts.get(b'edit'),
  2955                 opts.get('log'),
  3017                 opts.get(b'log'),
  2956                 opts.get('user'),
  3018                 opts.get(b'user'),
  2957                 opts.get('date'),
  3019                 opts.get(b'date'),
  2958                 opts.get('currentdate'),
  3020                 opts.get(b'currentdate'),
  2959                 opts.get('currentuser'),
  3021                 opts.get(b'currentuser'),
  2960                 opts.get('rev'),
  3022                 opts.get(b'rev'),
  2961             )
  3023             )
  2962         ):
  3024         ):
  2963             raise error.Abort(_("cannot specify any other flag with '--stop'"))
  3025             raise error.Abort(_(b"cannot specify any other flag with '--stop'"))
  2964         return _stopgraft(ui, repo, graftstate)
  3026         return _stopgraft(ui, repo, graftstate)
  2965     elif opts.get('abort'):
  3027     elif opts.get(b'abort'):
  2966         if opts.get('continue'):
  3028         if opts.get(b'continue'):
  2967             raise error.Abort(
  3029             raise error.Abort(
  2968                 _("cannot use '--continue' and " "'--abort' together")
  3030                 _(b"cannot use '--continue' and " b"'--abort' together")
  2969             )
  3031             )
  2970         if any(
  3032         if any(
  2971             (
  3033             (
  2972                 opts.get('edit'),
  3034                 opts.get(b'edit'),
  2973                 opts.get('log'),
  3035                 opts.get(b'log'),
  2974                 opts.get('user'),
  3036                 opts.get(b'user'),
  2975                 opts.get('date'),
  3037                 opts.get(b'date'),
  2976                 opts.get('currentdate'),
  3038                 opts.get(b'currentdate'),
  2977                 opts.get('currentuser'),
  3039                 opts.get(b'currentuser'),
  2978                 opts.get('rev'),
  3040                 opts.get(b'rev'),
  2979             )
  3041             )
  2980         ):
  3042         ):
  2981             raise error.Abort(_("cannot specify any other flag with '--abort'"))
  3043             raise error.Abort(
       
  3044                 _(b"cannot specify any other flag with '--abort'")
       
  3045             )
  2982 
  3046 
  2983         return cmdutil.abortgraft(ui, repo, graftstate)
  3047         return cmdutil.abortgraft(ui, repo, graftstate)
  2984     elif opts.get('continue'):
  3048     elif opts.get(b'continue'):
  2985         cont = True
  3049         cont = True
  2986         if revs:
  3050         if revs:
  2987             raise error.Abort(_("can't specify --continue and revisions"))
  3051             raise error.Abort(_(b"can't specify --continue and revisions"))
  2988         # read in unfinished revisions
  3052         # read in unfinished revisions
  2989         if graftstate.exists():
  3053         if graftstate.exists():
  2990             statedata = cmdutil.readgraftstate(repo, graftstate)
  3054             statedata = cmdutil.readgraftstate(repo, graftstate)
  2991             if statedata.get('date'):
  3055             if statedata.get(b'date'):
  2992                 opts['date'] = statedata['date']
  3056                 opts[b'date'] = statedata[b'date']
  2993             if statedata.get('user'):
  3057             if statedata.get(b'user'):
  2994                 opts['user'] = statedata['user']
  3058                 opts[b'user'] = statedata[b'user']
  2995             if statedata.get('log'):
  3059             if statedata.get(b'log'):
  2996                 opts['log'] = True
  3060                 opts[b'log'] = True
  2997             if statedata.get('no_commit'):
  3061             if statedata.get(b'no_commit'):
  2998                 opts['no_commit'] = statedata.get('no_commit')
  3062                 opts[b'no_commit'] = statedata.get(b'no_commit')
  2999             nodes = statedata['nodes']
  3063             nodes = statedata[b'nodes']
  3000             revs = [repo[node].rev() for node in nodes]
  3064             revs = [repo[node].rev() for node in nodes]
  3001         else:
  3065         else:
  3002             cmdutil.wrongtooltocontinue(repo, _('graft'))
  3066             cmdutil.wrongtooltocontinue(repo, _(b'graft'))
  3003     else:
  3067     else:
  3004         if not revs:
  3068         if not revs:
  3005             raise error.Abort(_('no revisions specified'))
  3069             raise error.Abort(_(b'no revisions specified'))
  3006         cmdutil.checkunfinished(repo)
  3070         cmdutil.checkunfinished(repo)
  3007         cmdutil.bailifchanged(repo)
  3071         cmdutil.bailifchanged(repo)
  3008         revs = scmutil.revrange(repo, revs)
  3072         revs = scmutil.revrange(repo, revs)
  3009 
  3073 
  3010     skipped = set()
  3074     skipped = set()
  3011     if basectx is None:
  3075     if basectx is None:
  3012         # check for merges
  3076         # check for merges
  3013         for rev in repo.revs('%ld and merge()', revs):
  3077         for rev in repo.revs(b'%ld and merge()', revs):
  3014             ui.warn(_('skipping ungraftable merge revision %d\n') % rev)
  3078             ui.warn(_(b'skipping ungraftable merge revision %d\n') % rev)
  3015             skipped.add(rev)
  3079             skipped.add(rev)
  3016     revs = [r for r in revs if r not in skipped]
  3080     revs = [r for r in revs if r not in skipped]
  3017     if not revs:
  3081     if not revs:
  3018         return -1
  3082         return -1
  3019     if basectx is not None and len(revs) != 1:
  3083     if basectx is not None and len(revs) != 1:
  3020         raise error.Abort(_('only one revision allowed with --base '))
  3084         raise error.Abort(_(b'only one revision allowed with --base '))
  3021 
  3085 
  3022     # Don't check in the --continue case, in effect retaining --force across
  3086     # Don't check in the --continue case, in effect retaining --force across
  3023     # --continues. That's because without --force, any revisions we decided to
  3087     # --continues. That's because without --force, any revisions we decided to
  3024     # skip would have been filtered out here, so they wouldn't have made their
  3088     # skip would have been filtered out here, so they wouldn't have made their
  3025     # way to the graftstate. With --force, any revisions we would have otherwise
  3089     # way to the graftstate. With --force, any revisions we would have otherwise
  3026     # skipped would not have been filtered out, and if they hadn't been applied
  3090     # skipped would not have been filtered out, and if they hadn't been applied
  3027     # already, they'd have been in the graftstate.
  3091     # already, they'd have been in the graftstate.
  3028     if not (cont or opts.get('force')) and basectx is None:
  3092     if not (cont or opts.get(b'force')) and basectx is None:
  3029         # check for ancestors of dest branch
  3093         # check for ancestors of dest branch
  3030         crev = repo['.'].rev()
  3094         crev = repo[b'.'].rev()
  3031         ancestors = repo.changelog.ancestors([crev], inclusive=True)
  3095         ancestors = repo.changelog.ancestors([crev], inclusive=True)
  3032         # XXX make this lazy in the future
  3096         # XXX make this lazy in the future
  3033         # don't mutate while iterating, create a copy
  3097         # don't mutate while iterating, create a copy
  3034         for rev in list(revs):
  3098         for rev in list(revs):
  3035             if rev in ancestors:
  3099             if rev in ancestors:
  3036                 ui.warn(
  3100                 ui.warn(
  3037                     _('skipping ancestor revision %d:%s\n') % (rev, repo[rev])
  3101                     _(b'skipping ancestor revision %d:%s\n') % (rev, repo[rev])
  3038                 )
  3102                 )
  3039                 # XXX remove on list is slow
  3103                 # XXX remove on list is slow
  3040                 revs.remove(rev)
  3104                 revs.remove(rev)
  3041         if not revs:
  3105         if not revs:
  3042             return -1
  3106             return -1
  3043 
  3107 
  3044         # analyze revs for earlier grafts
  3108         # analyze revs for earlier grafts
  3045         ids = {}
  3109         ids = {}
  3046         for ctx in repo.set("%ld", revs):
  3110         for ctx in repo.set(b"%ld", revs):
  3047             ids[ctx.hex()] = ctx.rev()
  3111             ids[ctx.hex()] = ctx.rev()
  3048             n = ctx.extra().get('source')
  3112             n = ctx.extra().get(b'source')
  3049             if n:
  3113             if n:
  3050                 ids[n] = ctx.rev()
  3114                 ids[n] = ctx.rev()
  3051 
  3115 
  3052         # check ancestors for earlier grafts
  3116         # check ancestors for earlier grafts
  3053         ui.debug('scanning for duplicate grafts\n')
  3117         ui.debug(b'scanning for duplicate grafts\n')
  3054 
  3118 
  3055         # The only changesets we can be sure doesn't contain grafts of any
  3119         # The only changesets we can be sure doesn't contain grafts of any
  3056         # revs, are the ones that are common ancestors of *all* revs:
  3120         # revs, are the ones that are common ancestors of *all* revs:
  3057         for rev in repo.revs('only(%d,ancestor(%ld))', crev, revs):
  3121         for rev in repo.revs(b'only(%d,ancestor(%ld))', crev, revs):
  3058             ctx = repo[rev]
  3122             ctx = repo[rev]
  3059             n = ctx.extra().get('source')
  3123             n = ctx.extra().get(b'source')
  3060             if n in ids:
  3124             if n in ids:
  3061                 try:
  3125                 try:
  3062                     r = repo[n].rev()
  3126                     r = repo[n].rev()
  3063                 except error.RepoLookupError:
  3127                 except error.RepoLookupError:
  3064                     r = None
  3128                     r = None
  3065                 if r in revs:
  3129                 if r in revs:
  3066                     ui.warn(
  3130                     ui.warn(
  3067                         _(
  3131                         _(
  3068                             'skipping revision %d:%s '
  3132                             b'skipping revision %d:%s '
  3069                             '(already grafted to %d:%s)\n'
  3133                             b'(already grafted to %d:%s)\n'
  3070                         )
  3134                         )
  3071                         % (r, repo[r], rev, ctx)
  3135                         % (r, repo[r], rev, ctx)
  3072                     )
  3136                     )
  3073                     revs.remove(r)
  3137                     revs.remove(r)
  3074                 elif ids[n] in revs:
  3138                 elif ids[n] in revs:
  3075                     if r is None:
  3139                     if r is None:
  3076                         ui.warn(
  3140                         ui.warn(
  3077                             _(
  3141                             _(
  3078                                 'skipping already grafted revision %d:%s '
  3142                                 b'skipping already grafted revision %d:%s '
  3079                                 '(%d:%s also has unknown origin %s)\n'
  3143                                 b'(%d:%s also has unknown origin %s)\n'
  3080                             )
  3144                             )
  3081                             % (ids[n], repo[ids[n]], rev, ctx, n[:12])
  3145                             % (ids[n], repo[ids[n]], rev, ctx, n[:12])
  3082                         )
  3146                         )
  3083                     else:
  3147                     else:
  3084                         ui.warn(
  3148                         ui.warn(
  3085                             _(
  3149                             _(
  3086                                 'skipping already grafted revision %d:%s '
  3150                                 b'skipping already grafted revision %d:%s '
  3087                                 '(%d:%s also has origin %d:%s)\n'
  3151                                 b'(%d:%s also has origin %d:%s)\n'
  3088                             )
  3152                             )
  3089                             % (ids[n], repo[ids[n]], rev, ctx, r, n[:12])
  3153                             % (ids[n], repo[ids[n]], rev, ctx, r, n[:12])
  3090                         )
  3154                         )
  3091                     revs.remove(ids[n])
  3155                     revs.remove(ids[n])
  3092             elif ctx.hex() in ids:
  3156             elif ctx.hex() in ids:
  3093                 r = ids[ctx.hex()]
  3157                 r = ids[ctx.hex()]
  3094                 if r in revs:
  3158                 if r in revs:
  3095                     ui.warn(
  3159                     ui.warn(
  3096                         _(
  3160                         _(
  3097                             'skipping already grafted revision %d:%s '
  3161                             b'skipping already grafted revision %d:%s '
  3098                             '(was grafted from %d:%s)\n'
  3162                             b'(was grafted from %d:%s)\n'
  3099                         )
  3163                         )
  3100                         % (r, repo[r], rev, ctx)
  3164                         % (r, repo[r], rev, ctx)
  3101                     )
  3165                     )
  3102                     revs.remove(r)
  3166                     revs.remove(r)
  3103         if not revs:
  3167         if not revs:
  3104             return -1
  3168             return -1
  3105 
  3169 
  3106     if opts.get('no_commit'):
  3170     if opts.get(b'no_commit'):
  3107         statedata['no_commit'] = True
  3171         statedata[b'no_commit'] = True
  3108     for pos, ctx in enumerate(repo.set("%ld", revs)):
  3172     for pos, ctx in enumerate(repo.set(b"%ld", revs)):
  3109         desc = '%d:%s "%s"' % (
  3173         desc = b'%d:%s "%s"' % (
  3110             ctx.rev(),
  3174             ctx.rev(),
  3111             ctx,
  3175             ctx,
  3112             ctx.description().split('\n', 1)[0],
  3176             ctx.description().split(b'\n', 1)[0],
  3113         )
  3177         )
  3114         names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node())
  3178         names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node())
  3115         if names:
  3179         if names:
  3116             desc += ' (%s)' % ' '.join(names)
  3180             desc += b' (%s)' % b' '.join(names)
  3117         ui.status(_('grafting %s\n') % desc)
  3181         ui.status(_(b'grafting %s\n') % desc)
  3118         if opts.get('dry_run'):
  3182         if opts.get(b'dry_run'):
  3119             continue
  3183             continue
  3120 
  3184 
  3121         source = ctx.extra().get('source')
  3185         source = ctx.extra().get(b'source')
  3122         extra = {}
  3186         extra = {}
  3123         if source:
  3187         if source:
  3124             extra['source'] = source
  3188             extra[b'source'] = source
  3125             extra['intermediate-source'] = ctx.hex()
  3189             extra[b'intermediate-source'] = ctx.hex()
  3126         else:
  3190         else:
  3127             extra['source'] = ctx.hex()
  3191             extra[b'source'] = ctx.hex()
  3128         user = ctx.user()
  3192         user = ctx.user()
  3129         if opts.get('user'):
  3193         if opts.get(b'user'):
  3130             user = opts['user']
  3194             user = opts[b'user']
  3131             statedata['user'] = user
  3195             statedata[b'user'] = user
  3132         date = ctx.date()
  3196         date = ctx.date()
  3133         if opts.get('date'):
  3197         if opts.get(b'date'):
  3134             date = opts['date']
  3198             date = opts[b'date']
  3135             statedata['date'] = date
  3199             statedata[b'date'] = date
  3136         message = ctx.description()
  3200         message = ctx.description()
  3137         if opts.get('log'):
  3201         if opts.get(b'log'):
  3138             message += '\n(grafted from %s)' % ctx.hex()
  3202             message += b'\n(grafted from %s)' % ctx.hex()
  3139             statedata['log'] = True
  3203             statedata[b'log'] = True
  3140 
  3204 
  3141         # we don't merge the first commit when continuing
  3205         # we don't merge the first commit when continuing
  3142         if not cont:
  3206         if not cont:
  3143             # perform the graft merge with p1(rev) as 'ancestor'
  3207             # perform the graft merge with p1(rev) as 'ancestor'
  3144             overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
  3208             overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
  3145             base = ctx.p1() if basectx is None else basectx
  3209             base = ctx.p1() if basectx is None else basectx
  3146             with ui.configoverride(overrides, 'graft'):
  3210             with ui.configoverride(overrides, b'graft'):
  3147                 stats = mergemod.graft(repo, ctx, base, ['local', 'graft'])
  3211                 stats = mergemod.graft(repo, ctx, base, [b'local', b'graft'])
  3148             # report any conflicts
  3212             # report any conflicts
  3149             if stats.unresolvedcount > 0:
  3213             if stats.unresolvedcount > 0:
  3150                 # write out state for --continue
  3214                 # write out state for --continue
  3151                 nodes = [repo[rev].hex() for rev in revs[pos:]]
  3215                 nodes = [repo[rev].hex() for rev in revs[pos:]]
  3152                 statedata['nodes'] = nodes
  3216                 statedata[b'nodes'] = nodes
  3153                 stateversion = 1
  3217                 stateversion = 1
  3154                 graftstate.save(stateversion, statedata)
  3218                 graftstate.save(stateversion, statedata)
  3155                 hint = _("use 'hg resolve' and 'hg graft --continue'")
  3219                 hint = _(b"use 'hg resolve' and 'hg graft --continue'")
  3156                 raise error.Abort(
  3220                 raise error.Abort(
  3157                     _("unresolved conflicts, can't continue"), hint=hint
  3221                     _(b"unresolved conflicts, can't continue"), hint=hint
  3158                 )
  3222                 )
  3159         else:
  3223         else:
  3160             cont = False
  3224             cont = False
  3161 
  3225 
  3162         # commit if --no-commit is false
  3226         # commit if --no-commit is false
  3163         if not opts.get('no_commit'):
  3227         if not opts.get(b'no_commit'):
  3164             node = repo.commit(
  3228             node = repo.commit(
  3165                 text=message, user=user, date=date, extra=extra, editor=editor
  3229                 text=message, user=user, date=date, extra=extra, editor=editor
  3166             )
  3230             )
  3167             if node is None:
  3231             if node is None:
  3168                 ui.warn(
  3232                 ui.warn(
  3169                     _('note: graft of %d:%s created no changes to commit\n')
  3233                     _(b'note: graft of %d:%s created no changes to commit\n')
  3170                     % (ctx.rev(), ctx)
  3234                     % (ctx.rev(), ctx)
  3171                 )
  3235                 )
  3172             # checking that newnodes exist because old state files won't have it
  3236             # checking that newnodes exist because old state files won't have it
  3173             elif statedata.get('newnodes') is not None:
  3237             elif statedata.get(b'newnodes') is not None:
  3174                 statedata['newnodes'].append(node)
  3238                 statedata[b'newnodes'].append(node)
  3175 
  3239 
  3176     # remove state when we complete successfully
  3240     # remove state when we complete successfully
  3177     if not opts.get('dry_run'):
  3241     if not opts.get(b'dry_run'):
  3178         graftstate.delete()
  3242         graftstate.delete()
  3179 
  3243 
  3180     return 0
  3244     return 0
  3181 
  3245 
  3182 
  3246 
  3183 def _stopgraft(ui, repo, graftstate):
  3247 def _stopgraft(ui, repo, graftstate):
  3184     """stop the interrupted graft"""
  3248     """stop the interrupted graft"""
  3185     if not graftstate.exists():
  3249     if not graftstate.exists():
  3186         raise error.Abort(_("no interrupted graft found"))
  3250         raise error.Abort(_(b"no interrupted graft found"))
  3187     pctx = repo['.']
  3251     pctx = repo[b'.']
  3188     hg.updaterepo(repo, pctx.node(), overwrite=True)
  3252     hg.updaterepo(repo, pctx.node(), overwrite=True)
  3189     graftstate.delete()
  3253     graftstate.delete()
  3190     ui.status(_("stopped the interrupted graft\n"))
  3254     ui.status(_(b"stopped the interrupted graft\n"))
  3191     ui.status(_("working directory is now at %s\n") % pctx.hex()[:12])
  3255     ui.status(_(b"working directory is now at %s\n") % pctx.hex()[:12])
  3192     return 0
  3256     return 0
  3193 
  3257 
  3194 
  3258 
  3195 statemod.addunfinished(
  3259 statemod.addunfinished(
  3196     'graft',
  3260     b'graft',
  3197     fname='graftstate',
  3261     fname=b'graftstate',
  3198     clearable=True,
  3262     clearable=True,
  3199     stopflag=True,
  3263     stopflag=True,
  3200     continueflag=True,
  3264     continueflag=True,
  3201     abortfunc=cmdutil.hgabortgraft,
  3265     abortfunc=cmdutil.hgabortgraft,
  3202     cmdhint=_("use 'hg graft --continue' or 'hg graft --stop' to stop"),
  3266     cmdhint=_(b"use 'hg graft --continue' or 'hg graft --stop' to stop"),
  3203 )
  3267 )
  3204 
  3268 
  3205 
  3269 
  3206 @command(
  3270 @command(
  3207     'grep',
  3271     b'grep',
  3208     [
  3272     [
  3209         ('0', 'print0', None, _('end fields with NUL')),
  3273         (b'0', b'print0', None, _(b'end fields with NUL')),
  3210         ('', 'all', None, _('print all revisions that match (DEPRECATED) ')),
  3274         (b'', b'all', None, _(b'print all revisions that match (DEPRECATED) ')),
  3211         (
  3275         (
  3212             '',
  3276             b'',
  3213             'diff',
  3277             b'diff',
  3214             None,
       
  3215             _('print all revisions when the term was introduced ' 'or removed'),
       
  3216         ),
       
  3217         ('a', 'text', None, _('treat all files as text')),
       
  3218         (
       
  3219             'f',
       
  3220             'follow',
       
  3221             None,
  3278             None,
  3222             _(
  3279             _(
  3223                 'follow changeset history,'
  3280                 b'print all revisions when the term was introduced '
  3224                 ' or file history across copies and renames'
  3281                 b'or removed'
  3225             ),
  3282             ),
  3226         ),
  3283         ),
  3227         ('i', 'ignore-case', None, _('ignore case when matching')),
  3284         (b'a', b'text', None, _(b'treat all files as text')),
  3228         (
  3285         (
  3229             'l',
  3286             b'f',
  3230             'files-with-matches',
  3287             b'follow',
  3231             None,
       
  3232             _('print only filenames and revisions that match'),
       
  3233         ),
       
  3234         ('n', 'line-number', None, _('print matching line numbers')),
       
  3235         (
       
  3236             'r',
       
  3237             'rev',
       
  3238             [],
       
  3239             _('only search files changed within revision range'),
       
  3240             _('REV'),
       
  3241         ),
       
  3242         (
       
  3243             '',
       
  3244             'all-files',
       
  3245             None,
  3288             None,
  3246             _(
  3289             _(
  3247                 'include all files in the changeset while grepping (EXPERIMENTAL)'
  3290                 b'follow changeset history,'
       
  3291                 b' or file history across copies and renames'
  3248             ),
  3292             ),
  3249         ),
  3293         ),
  3250         ('u', 'user', None, _('list the author (long with -v)')),
  3294         (b'i', b'ignore-case', None, _(b'ignore case when matching')),
  3251         ('d', 'date', None, _('list the date (short with -q)')),
  3295         (
       
  3296             b'l',
       
  3297             b'files-with-matches',
       
  3298             None,
       
  3299             _(b'print only filenames and revisions that match'),
       
  3300         ),
       
  3301         (b'n', b'line-number', None, _(b'print matching line numbers')),
       
  3302         (
       
  3303             b'r',
       
  3304             b'rev',
       
  3305             [],
       
  3306             _(b'only search files changed within revision range'),
       
  3307             _(b'REV'),
       
  3308         ),
       
  3309         (
       
  3310             b'',
       
  3311             b'all-files',
       
  3312             None,
       
  3313             _(
       
  3314                 b'include all files in the changeset while grepping (EXPERIMENTAL)'
       
  3315             ),
       
  3316         ),
       
  3317         (b'u', b'user', None, _(b'list the author (long with -v)')),
       
  3318         (b'd', b'date', None, _(b'list the date (short with -q)')),
  3252     ]
  3319     ]
  3253     + formatteropts
  3320     + formatteropts
  3254     + walkopts,
  3321     + walkopts,
  3255     _('[OPTION]... PATTERN [FILE]...'),
  3322     _(b'[OPTION]... PATTERN [FILE]...'),
  3256     helpcategory=command.CATEGORY_FILE_CONTENTS,
  3323     helpcategory=command.CATEGORY_FILE_CONTENTS,
  3257     inferrepo=True,
  3324     inferrepo=True,
  3258     intents={INTENT_READONLY},
  3325     intents={INTENT_READONLY},
  3259 )
  3326 )
  3260 def grep(ui, repo, pattern, *pats, **opts):
  3327 def grep(ui, repo, pattern, *pats, **opts):
  3297       See :hg:`help templates.operators` for the list expansion syntax.
  3364       See :hg:`help templates.operators` for the list expansion syntax.
  3298 
  3365 
  3299     Returns 0 if a match is found, 1 otherwise.
  3366     Returns 0 if a match is found, 1 otherwise.
  3300     """
  3367     """
  3301     opts = pycompat.byteskwargs(opts)
  3368     opts = pycompat.byteskwargs(opts)
  3302     diff = opts.get('all') or opts.get('diff')
  3369     diff = opts.get(b'all') or opts.get(b'diff')
  3303     all_files = opts.get('all_files')
  3370     all_files = opts.get(b'all_files')
  3304     if diff and opts.get('all_files'):
  3371     if diff and opts.get(b'all_files'):
  3305         raise error.Abort(_('--diff and --all-files are mutually exclusive'))
  3372         raise error.Abort(_(b'--diff and --all-files are mutually exclusive'))
  3306     # TODO: remove "not opts.get('rev')" if --all-files -rMULTIREV gets working
  3373     # TODO: remove "not opts.get('rev')" if --all-files -rMULTIREV gets working
  3307     if opts.get('all_files') is None and not opts.get('rev') and not diff:
  3374     if opts.get(b'all_files') is None and not opts.get(b'rev') and not diff:
  3308         # experimental config: commands.grep.all-files
  3375         # experimental config: commands.grep.all-files
  3309         opts['all_files'] = ui.configbool('commands', 'grep.all-files')
  3376         opts[b'all_files'] = ui.configbool(b'commands', b'grep.all-files')
  3310     plaingrep = opts.get('all_files') and not opts.get('rev')
  3377     plaingrep = opts.get(b'all_files') and not opts.get(b'rev')
  3311     if plaingrep:
  3378     if plaingrep:
  3312         opts['rev'] = ['wdir()']
  3379         opts[b'rev'] = [b'wdir()']
  3313 
  3380 
  3314     reflags = re.M
  3381     reflags = re.M
  3315     if opts.get('ignore_case'):
  3382     if opts.get(b'ignore_case'):
  3316         reflags |= re.I
  3383         reflags |= re.I
  3317     try:
  3384     try:
  3318         regexp = util.re.compile(pattern, reflags)
  3385         regexp = util.re.compile(pattern, reflags)
  3319     except re.error as inst:
  3386     except re.error as inst:
  3320         ui.warn(_("grep: invalid match pattern: %s\n") % pycompat.bytestr(inst))
  3387         ui.warn(
       
  3388             _(b"grep: invalid match pattern: %s\n") % pycompat.bytestr(inst)
       
  3389         )
  3321         return 1
  3390         return 1
  3322     sep, eol = ':', '\n'
  3391     sep, eol = b':', b'\n'
  3323     if opts.get('print0'):
  3392     if opts.get(b'print0'):
  3324         sep = eol = '\0'
  3393         sep = eol = b'\0'
  3325 
  3394 
  3326     getfile = util.lrucachefunc(repo.file)
  3395     getfile = util.lrucachefunc(repo.file)
  3327 
  3396 
  3328     def matchlines(body):
  3397     def matchlines(body):
  3329         begin = 0
  3398         begin = 0
  3331         while begin < len(body):
  3400         while begin < len(body):
  3332             match = regexp.search(body, begin)
  3401             match = regexp.search(body, begin)
  3333             if not match:
  3402             if not match:
  3334                 break
  3403                 break
  3335             mstart, mend = match.span()
  3404             mstart, mend = match.span()
  3336             linenum += body.count('\n', begin, mstart) + 1
  3405             linenum += body.count(b'\n', begin, mstart) + 1
  3337             lstart = body.rfind('\n', begin, mstart) + 1 or begin
  3406             lstart = body.rfind(b'\n', begin, mstart) + 1 or begin
  3338             begin = body.find('\n', mend) + 1 or len(body) + 1
  3407             begin = body.find(b'\n', mend) + 1 or len(body) + 1
  3339             lend = begin - 1
  3408             lend = begin - 1
  3340             yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
  3409             yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
  3341 
  3410 
  3342     class linestate(object):
  3411     class linestate(object):
  3343         def __init__(self, line, linenum, colstart, colend):
  3412         def __init__(self, line, linenum, colstart, colend):
  3376     def difflinestates(a, b):
  3445     def difflinestates(a, b):
  3377         sm = difflib.SequenceMatcher(None, a, b)
  3446         sm = difflib.SequenceMatcher(None, a, b)
  3378         for tag, alo, ahi, blo, bhi in sm.get_opcodes():
  3447         for tag, alo, ahi, blo, bhi in sm.get_opcodes():
  3379             if tag == r'insert':
  3448             if tag == r'insert':
  3380                 for i in pycompat.xrange(blo, bhi):
  3449                 for i in pycompat.xrange(blo, bhi):
  3381                     yield ('+', b[i])
  3450                     yield (b'+', b[i])
  3382             elif tag == r'delete':
  3451             elif tag == r'delete':
  3383                 for i in pycompat.xrange(alo, ahi):
  3452                 for i in pycompat.xrange(alo, ahi):
  3384                     yield ('-', a[i])
  3453                     yield (b'-', a[i])
  3385             elif tag == r'replace':
  3454             elif tag == r'replace':
  3386                 for i in pycompat.xrange(alo, ahi):
  3455                 for i in pycompat.xrange(alo, ahi):
  3387                     yield ('-', a[i])
  3456                     yield (b'-', a[i])
  3388                 for i in pycompat.xrange(blo, bhi):
  3457                 for i in pycompat.xrange(blo, bhi):
  3389                     yield ('+', b[i])
  3458                     yield (b'+', b[i])
  3390 
  3459 
  3391     uipathfn = scmutil.getuipathfn(repo)
  3460     uipathfn = scmutil.getuipathfn(repo)
  3392 
  3461 
  3393     def display(fm, fn, ctx, pstates, states):
  3462     def display(fm, fn, ctx, pstates, states):
  3394         rev = scmutil.intrev(ctx)
  3463         rev = scmutil.intrev(ctx)
  3395         if fm.isplain():
  3464         if fm.isplain():
  3396             formatuser = ui.shortuser
  3465             formatuser = ui.shortuser
  3397         else:
  3466         else:
  3398             formatuser = pycompat.bytestr
  3467             formatuser = pycompat.bytestr
  3399         if ui.quiet:
  3468         if ui.quiet:
  3400             datefmt = '%Y-%m-%d'
  3469             datefmt = b'%Y-%m-%d'
  3401         else:
  3470         else:
  3402             datefmt = '%a %b %d %H:%M:%S %Y %1%2'
  3471             datefmt = b'%a %b %d %H:%M:%S %Y %1%2'
  3403         found = False
  3472         found = False
  3404 
  3473 
  3405         @util.cachefunc
  3474         @util.cachefunc
  3406         def binary():
  3475         def binary():
  3407             flog = getfile(fn)
  3476             flog = getfile(fn)
  3408             try:
  3477             try:
  3409                 return stringutil.binary(flog.read(ctx.filenode(fn)))
  3478                 return stringutil.binary(flog.read(ctx.filenode(fn)))
  3410             except error.WdirUnsupported:
  3479             except error.WdirUnsupported:
  3411                 return ctx[fn].isbinary()
  3480                 return ctx[fn].isbinary()
  3412 
  3481 
  3413         fieldnamemap = {'linenumber': 'lineno'}
  3482         fieldnamemap = {b'linenumber': b'lineno'}
  3414         if diff:
  3483         if diff:
  3415             iter = difflinestates(pstates, states)
  3484             iter = difflinestates(pstates, states)
  3416         else:
  3485         else:
  3417             iter = [('', l) for l in states]
  3486             iter = [(b'', l) for l in states]
  3418         for change, l in iter:
  3487         for change, l in iter:
  3419             fm.startitem()
  3488             fm.startitem()
  3420             fm.context(ctx=ctx)
  3489             fm.context(ctx=ctx)
  3421             fm.data(node=fm.hexfunc(scmutil.binnode(ctx)), path=fn)
  3490             fm.data(node=fm.hexfunc(scmutil.binnode(ctx)), path=fn)
  3422             fm.plain(uipathfn(fn), label='grep.filename')
  3491             fm.plain(uipathfn(fn), label=b'grep.filename')
  3423 
  3492 
  3424             cols = [
  3493             cols = [
  3425                 ('rev', '%d', rev, not plaingrep, ''),
  3494                 (b'rev', b'%d', rev, not plaingrep, b''),
  3426                 ('linenumber', '%d', l.linenum, opts.get('line_number'), ''),
  3495                 (
       
  3496                     b'linenumber',
       
  3497                     b'%d',
       
  3498                     l.linenum,
       
  3499                     opts.get(b'line_number'),
       
  3500                     b'',
       
  3501                 ),
  3427             ]
  3502             ]
  3428             if diff:
  3503             if diff:
  3429                 cols.append(
  3504                 cols.append(
  3430                     (
  3505                     (
  3431                         'change',
  3506                         b'change',
  3432                         '%s',
  3507                         b'%s',
  3433                         change,
  3508                         change,
  3434                         True,
  3509                         True,
  3435                         'grep.inserted ' if change == '+' else 'grep.deleted ',
  3510                         b'grep.inserted '
       
  3511                         if change == b'+'
       
  3512                         else b'grep.deleted ',
  3436                     )
  3513                     )
  3437                 )
  3514                 )
  3438             cols.extend(
  3515             cols.extend(
  3439                 [
  3516                 [
  3440                     (
  3517                     (
  3441                         'user',
  3518                         b'user',
  3442                         '%s',
  3519                         b'%s',
  3443                         formatuser(ctx.user()),
  3520                         formatuser(ctx.user()),
  3444                         opts.get('user'),
  3521                         opts.get(b'user'),
  3445                         '',
  3522                         b'',
  3446                     ),
  3523                     ),
  3447                     (
  3524                     (
  3448                         'date',
  3525                         b'date',
  3449                         '%s',
  3526                         b'%s',
  3450                         fm.formatdate(ctx.date(), datefmt),
  3527                         fm.formatdate(ctx.date(), datefmt),
  3451                         opts.get('date'),
  3528                         opts.get(b'date'),
  3452                         '',
  3529                         b'',
  3453                     ),
  3530                     ),
  3454                 ]
  3531                 ]
  3455             )
  3532             )
  3456             for name, fmt, data, cond, extra_label in cols:
  3533             for name, fmt, data, cond, extra_label in cols:
  3457                 if cond:
  3534                 if cond:
  3458                     fm.plain(sep, label='grep.sep')
  3535                     fm.plain(sep, label=b'grep.sep')
  3459                 field = fieldnamemap.get(name, name)
  3536                 field = fieldnamemap.get(name, name)
  3460                 label = extra_label + ('grep.%s' % name)
  3537                 label = extra_label + (b'grep.%s' % name)
  3461                 fm.condwrite(cond, field, fmt, data, label=label)
  3538                 fm.condwrite(cond, field, fmt, data, label=label)
  3462             if not opts.get('files_with_matches'):
  3539             if not opts.get(b'files_with_matches'):
  3463                 fm.plain(sep, label='grep.sep')
  3540                 fm.plain(sep, label=b'grep.sep')
  3464                 if not opts.get('text') and binary():
  3541                 if not opts.get(b'text') and binary():
  3465                     fm.plain(_(" Binary file matches"))
  3542                     fm.plain(_(b" Binary file matches"))
  3466                 else:
  3543                 else:
  3467                     displaymatches(fm.nested('texts', tmpl='{text}'), l)
  3544                     displaymatches(fm.nested(b'texts', tmpl=b'{text}'), l)
  3468             fm.plain(eol)
  3545             fm.plain(eol)
  3469             found = True
  3546             found = True
  3470             if opts.get('files_with_matches'):
  3547             if opts.get(b'files_with_matches'):
  3471                 break
  3548                 break
  3472         return found
  3549         return found
  3473 
  3550 
  3474     def displaymatches(fm, l):
  3551     def displaymatches(fm, l):
  3475         p = 0
  3552         p = 0
  3476         for s, e in l.findpos():
  3553         for s, e in l.findpos():
  3477             if p < s:
  3554             if p < s:
  3478                 fm.startitem()
  3555                 fm.startitem()
  3479                 fm.write('text', '%s', l.line[p:s])
  3556                 fm.write(b'text', b'%s', l.line[p:s])
  3480                 fm.data(matched=False)
  3557                 fm.data(matched=False)
  3481             fm.startitem()
  3558             fm.startitem()
  3482             fm.write('text', '%s', l.line[s:e], label='grep.match')
  3559             fm.write(b'text', b'%s', l.line[s:e], label=b'grep.match')
  3483             fm.data(matched=True)
  3560             fm.data(matched=True)
  3484             p = e
  3561             p = e
  3485         if p < len(l.line):
  3562         if p < len(l.line):
  3486             fm.startitem()
  3563             fm.startitem()
  3487             fm.write('text', '%s', l.line[p:])
  3564             fm.write(b'text', b'%s', l.line[p:])
  3488             fm.data(matched=False)
  3565             fm.data(matched=False)
  3489         fm.end()
  3566         fm.end()
  3490 
  3567 
  3491     skip = set()
  3568     skip = set()
  3492     revfiles = {}
  3569     revfiles = {}
  3493     match = scmutil.match(repo[None], pats, opts)
  3570     match = scmutil.match(repo[None], pats, opts)
  3494     found = False
  3571     found = False
  3495     follow = opts.get('follow')
  3572     follow = opts.get(b'follow')
  3496 
  3573 
  3497     getrenamed = scmutil.getrenamedfn(repo)
  3574     getrenamed = scmutil.getrenamedfn(repo)
  3498 
  3575 
  3499     def prep(ctx, fns):
  3576     def prep(ctx, fns):
  3500         rev = ctx.rev()
  3577         rev = ctx.rev()
  3534                     fnode = pctx.filenode(pfn)
  3611                     fnode = pctx.filenode(pfn)
  3535                     grepbody(pfn, parent, flog.read(fnode))
  3612                     grepbody(pfn, parent, flog.read(fnode))
  3536                 except error.LookupError:
  3613                 except error.LookupError:
  3537                     pass
  3614                     pass
  3538 
  3615 
  3539     ui.pager('grep')
  3616     ui.pager(b'grep')
  3540     fm = ui.formatter('grep', opts)
  3617     fm = ui.formatter(b'grep', opts)
  3541     for ctx in cmdutil.walkchangerevs(repo, match, opts, prep):
  3618     for ctx in cmdutil.walkchangerevs(repo, match, opts, prep):
  3542         rev = ctx.rev()
  3619         rev = ctx.rev()
  3543         parent = ctx.p1().rev()
  3620         parent = ctx.p1().rev()
  3544         for fn in sorted(revfiles.get(rev, [])):
  3621         for fn in sorted(revfiles.get(rev, [])):
  3545             states = matches[rev][fn]
  3622             states = matches[rev][fn]
  3565 
  3642 
  3566     return not found
  3643     return not found
  3567 
  3644 
  3568 
  3645 
  3569 @command(
  3646 @command(
  3570     'heads',
  3647     b'heads',
  3571     [
  3648     [
  3572         (
  3649         (
  3573             'r',
  3650             b'r',
  3574             'rev',
  3651             b'rev',
  3575             '',
  3652             b'',
  3576             _('show only heads which are descendants of STARTREV'),
  3653             _(b'show only heads which are descendants of STARTREV'),
  3577             _('STARTREV'),
  3654             _(b'STARTREV'),
  3578         ),
  3655         ),
  3579         ('t', 'topo', False, _('show topological heads only')),
  3656         (b't', b'topo', False, _(b'show topological heads only')),
  3580         ('a', 'active', False, _('show active branchheads only (DEPRECATED)')),
  3657         (
  3581         ('c', 'closed', False, _('show normal and closed branch heads')),
  3658             b'a',
       
  3659             b'active',
       
  3660             False,
       
  3661             _(b'show active branchheads only (DEPRECATED)'),
       
  3662         ),
       
  3663         (b'c', b'closed', False, _(b'show normal and closed branch heads')),
  3582     ]
  3664     ]
  3583     + templateopts,
  3665     + templateopts,
  3584     _('[-ct] [-r STARTREV] [REV]...'),
  3666     _(b'[-ct] [-r STARTREV] [REV]...'),
  3585     helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
  3667     helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
  3586     intents={INTENT_READONLY},
  3668     intents={INTENT_READONLY},
  3587 )
  3669 )
  3588 def heads(ui, repo, *branchrevs, **opts):
  3670 def heads(ui, repo, *branchrevs, **opts):
  3589     """show branch heads
  3671     """show branch heads
  3610     Returns 0 if matching heads are found, 1 if not.
  3692     Returns 0 if matching heads are found, 1 if not.
  3611     """
  3693     """
  3612 
  3694 
  3613     opts = pycompat.byteskwargs(opts)
  3695     opts = pycompat.byteskwargs(opts)
  3614     start = None
  3696     start = None
  3615     rev = opts.get('rev')
  3697     rev = opts.get(b'rev')
  3616     if rev:
  3698     if rev:
  3617         repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
  3699         repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
  3618         start = scmutil.revsingle(repo, rev, None).node()
  3700         start = scmutil.revsingle(repo, rev, None).node()
  3619 
  3701 
  3620     if opts.get('topo'):
  3702     if opts.get(b'topo'):
  3621         heads = [repo[h] for h in repo.heads(start)]
  3703         heads = [repo[h] for h in repo.heads(start)]
  3622     else:
  3704     else:
  3623         heads = []
  3705         heads = []
  3624         for branch in repo.branchmap():
  3706         for branch in repo.branchmap():
  3625             heads += repo.branchheads(branch, start, opts.get('closed'))
  3707             heads += repo.branchheads(branch, start, opts.get(b'closed'))
  3626         heads = [repo[h] for h in heads]
  3708         heads = [repo[h] for h in heads]
  3627 
  3709 
  3628     if branchrevs:
  3710     if branchrevs:
  3629         branches = set(
  3711         branches = set(
  3630             repo[r].branch() for r in scmutil.revrange(repo, branchrevs)
  3712             repo[r].branch() for r in scmutil.revrange(repo, branchrevs)
  3631         )
  3713         )
  3632         heads = [h for h in heads if h.branch() in branches]
  3714         heads = [h for h in heads if h.branch() in branches]
  3633 
  3715 
  3634     if opts.get('active') and branchrevs:
  3716     if opts.get(b'active') and branchrevs:
  3635         dagheads = repo.heads(start)
  3717         dagheads = repo.heads(start)
  3636         heads = [h for h in heads if h.node() in dagheads]
  3718         heads = [h for h in heads if h.node() in dagheads]
  3637 
  3719 
  3638     if branchrevs:
  3720     if branchrevs:
  3639         haveheads = set(h.branch() for h in heads)
  3721         haveheads = set(h.branch() for h in heads)
  3640         if branches - haveheads:
  3722         if branches - haveheads:
  3641             headless = ', '.join(b for b in branches - haveheads)
  3723             headless = b', '.join(b for b in branches - haveheads)
  3642             msg = _('no open branch heads found on branches %s')
  3724             msg = _(b'no open branch heads found on branches %s')
  3643             if opts.get('rev'):
  3725             if opts.get(b'rev'):
  3644                 msg += _(' (started at %s)') % opts['rev']
  3726                 msg += _(b' (started at %s)') % opts[b'rev']
  3645             ui.warn((msg + '\n') % headless)
  3727             ui.warn((msg + b'\n') % headless)
  3646 
  3728 
  3647     if not heads:
  3729     if not heads:
  3648         return 1
  3730         return 1
  3649 
  3731 
  3650     ui.pager('heads')
  3732     ui.pager(b'heads')
  3651     heads = sorted(heads, key=lambda x: -(x.rev()))
  3733     heads = sorted(heads, key=lambda x: -(x.rev()))
  3652     displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
  3734     displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
  3653     for ctx in heads:
  3735     for ctx in heads:
  3654         displayer.show(ctx)
  3736         displayer.show(ctx)
  3655     displayer.close()
  3737     displayer.close()
  3656 
  3738 
  3657 
  3739 
  3658 @command(
  3740 @command(
  3659     'help',
  3741     b'help',
  3660     [
  3742     [
  3661         ('e', 'extension', None, _('show only help for extensions')),
  3743         (b'e', b'extension', None, _(b'show only help for extensions')),
  3662         ('c', 'command', None, _('show only help for commands')),
  3744         (b'c', b'command', None, _(b'show only help for commands')),
  3663         ('k', 'keyword', None, _('show topics matching keyword')),
  3745         (b'k', b'keyword', None, _(b'show topics matching keyword')),
  3664         (
  3746         (
  3665             's',
  3747             b's',
  3666             'system',
  3748             b'system',
  3667             [],
  3749             [],
  3668             _('show help for specific platform(s)'),
  3750             _(b'show help for specific platform(s)'),
  3669             _('PLATFORM'),
  3751             _(b'PLATFORM'),
  3670         ),
  3752         ),
  3671     ],
  3753     ],
  3672     _('[-eck] [-s PLATFORM] [TOPIC]'),
  3754     _(b'[-eck] [-s PLATFORM] [TOPIC]'),
  3673     helpcategory=command.CATEGORY_HELP,
  3755     helpcategory=command.CATEGORY_HELP,
  3674     norepo=True,
  3756     norepo=True,
  3675     intents={INTENT_READONLY},
  3757     intents={INTENT_READONLY},
  3676 )
  3758 )
  3677 def help_(ui, name=None, **opts):
  3759 def help_(ui, name=None, **opts):
  3685     Returns 0 if successful.
  3767     Returns 0 if successful.
  3686     """
  3768     """
  3687 
  3769 
  3688     keep = opts.get(r'system') or []
  3770     keep = opts.get(r'system') or []
  3689     if len(keep) == 0:
  3771     if len(keep) == 0:
  3690         if pycompat.sysplatform.startswith('win'):
  3772         if pycompat.sysplatform.startswith(b'win'):
  3691             keep.append('windows')
  3773             keep.append(b'windows')
  3692         elif pycompat.sysplatform == 'OpenVMS':
  3774         elif pycompat.sysplatform == b'OpenVMS':
  3693             keep.append('vms')
  3775             keep.append(b'vms')
  3694         elif pycompat.sysplatform == 'plan9':
  3776         elif pycompat.sysplatform == b'plan9':
  3695             keep.append('plan9')
  3777             keep.append(b'plan9')
  3696         else:
  3778         else:
  3697             keep.append('unix')
  3779             keep.append(b'unix')
  3698             keep.append(pycompat.sysplatform.lower())
  3780             keep.append(pycompat.sysplatform.lower())
  3699     if ui.verbose:
  3781     if ui.verbose:
  3700         keep.append('verbose')
  3782         keep.append(b'verbose')
  3701 
  3783 
  3702     commands = sys.modules[__name__]
  3784     commands = sys.modules[__name__]
  3703     formatted = help.formattedhelp(ui, commands, name, keep=keep, **opts)
  3785     formatted = help.formattedhelp(ui, commands, name, keep=keep, **opts)
  3704     ui.pager('help')
  3786     ui.pager(b'help')
  3705     ui.write(formatted)
  3787     ui.write(formatted)
  3706 
  3788 
  3707 
  3789 
  3708 @command(
  3790 @command(
  3709     'identify|id',
  3791     b'identify|id',
  3710     [
  3792     [
  3711         ('r', 'rev', '', _('identify the specified revision'), _('REV')),
  3793         (b'r', b'rev', b'', _(b'identify the specified revision'), _(b'REV')),
  3712         ('n', 'num', None, _('show local revision number')),
  3794         (b'n', b'num', None, _(b'show local revision number')),
  3713         ('i', 'id', None, _('show global revision id')),
  3795         (b'i', b'id', None, _(b'show global revision id')),
  3714         ('b', 'branch', None, _('show branch')),
  3796         (b'b', b'branch', None, _(b'show branch')),
  3715         ('t', 'tags', None, _('show tags')),
  3797         (b't', b'tags', None, _(b'show tags')),
  3716         ('B', 'bookmarks', None, _('show bookmarks')),
  3798         (b'B', b'bookmarks', None, _(b'show bookmarks')),
  3717     ]
  3799     ]
  3718     + remoteopts
  3800     + remoteopts
  3719     + formatteropts,
  3801     + formatteropts,
  3720     _('[-nibtB] [-r REV] [SOURCE]'),
  3802     _(b'[-nibtB] [-r REV] [SOURCE]'),
  3721     helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
  3803     helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
  3722     optionalrepo=True,
  3804     optionalrepo=True,
  3723     intents={INTENT_READONLY},
  3805     intents={INTENT_READONLY},
  3724 )
  3806 )
  3725 def identify(
  3807 def identify(
  3781     """
  3863     """
  3782 
  3864 
  3783     opts = pycompat.byteskwargs(opts)
  3865     opts = pycompat.byteskwargs(opts)
  3784     if not repo and not source:
  3866     if not repo and not source:
  3785         raise error.Abort(
  3867         raise error.Abort(
  3786             _("there is no Mercurial repository here " "(.hg not found)")
  3868             _(b"there is no Mercurial repository here " b"(.hg not found)")
  3787         )
  3869         )
  3788 
  3870 
  3789     default = not (num or id or branch or tags or bookmarks)
  3871     default = not (num or id or branch or tags or bookmarks)
  3790     output = []
  3872     output = []
  3791     revs = []
  3873     revs = []
  3794         source, branches = hg.parseurl(ui.expandpath(source))
  3876         source, branches = hg.parseurl(ui.expandpath(source))
  3795         peer = hg.peer(repo or ui, opts, source)  # only pass ui when no repo
  3877         peer = hg.peer(repo or ui, opts, source)  # only pass ui when no repo
  3796         repo = peer.local()
  3878         repo = peer.local()
  3797         revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
  3879         revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
  3798 
  3880 
  3799     fm = ui.formatter('identify', opts)
  3881     fm = ui.formatter(b'identify', opts)
  3800     fm.startitem()
  3882     fm.startitem()
  3801 
  3883 
  3802     if not repo:
  3884     if not repo:
  3803         if num or branch or tags:
  3885         if num or branch or tags:
  3804             raise error.Abort(
  3886             raise error.Abort(
  3805                 _("can't query remote revision number, branch, or tags")
  3887                 _(b"can't query remote revision number, branch, or tags")
  3806             )
  3888             )
  3807         if not rev and revs:
  3889         if not rev and revs:
  3808             rev = revs[0]
  3890             rev = revs[0]
  3809         if not rev:
  3891         if not rev:
  3810             rev = "tip"
  3892             rev = b"tip"
  3811 
  3893 
  3812         remoterev = peer.lookup(rev)
  3894         remoterev = peer.lookup(rev)
  3813         hexrev = fm.hexfunc(remoterev)
  3895         hexrev = fm.hexfunc(remoterev)
  3814         if default or id:
  3896         if default or id:
  3815             output = [hexrev]
  3897             output = [hexrev]
  3817 
  3899 
  3818         @util.cachefunc
  3900         @util.cachefunc
  3819         def getbms():
  3901         def getbms():
  3820             bms = []
  3902             bms = []
  3821 
  3903 
  3822             if 'bookmarks' in peer.listkeys('namespaces'):
  3904             if b'bookmarks' in peer.listkeys(b'namespaces'):
  3823                 hexremoterev = hex(remoterev)
  3905                 hexremoterev = hex(remoterev)
  3824                 bms = [
  3906                 bms = [
  3825                     bm
  3907                     bm
  3826                     for bm, bmr in peer.listkeys('bookmarks').iteritems()
  3908                     for bm, bmr in peer.listkeys(b'bookmarks').iteritems()
  3827                     if bmr == hexremoterev
  3909                     if bmr == hexremoterev
  3828                 ]
  3910                 ]
  3829 
  3911 
  3830             return sorted(bms)
  3912             return sorted(bms)
  3831 
  3913 
  3832         if fm.isplain():
  3914         if fm.isplain():
  3833             if bookmarks:
  3915             if bookmarks:
  3834                 output.extend(getbms())
  3916                 output.extend(getbms())
  3835             elif default and not ui.quiet:
  3917             elif default and not ui.quiet:
  3836                 # multiple bookmarks for a single parent separated by '/'
  3918                 # multiple bookmarks for a single parent separated by '/'
  3837                 bm = '/'.join(getbms())
  3919                 bm = b'/'.join(getbms())
  3838                 if bm:
  3920                 if bm:
  3839                     output.append(bm)
  3921                     output.append(bm)
  3840         else:
  3922         else:
  3841             fm.data(node=hex(remoterev))
  3923             fm.data(node=hex(remoterev))
  3842             if bookmarks or 'bookmarks' in fm.datahint():
  3924             if bookmarks or b'bookmarks' in fm.datahint():
  3843                 fm.data(bookmarks=fm.formatlist(getbms(), name='bookmark'))
  3925                 fm.data(bookmarks=fm.formatlist(getbms(), name=b'bookmark'))
  3844     else:
  3926     else:
  3845         if rev:
  3927         if rev:
  3846             repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
  3928             repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
  3847         ctx = scmutil.revsingle(repo, rev, None)
  3929         ctx = scmutil.revsingle(repo, rev, None)
  3848 
  3930 
  3849         if ctx.rev() is None:
  3931         if ctx.rev() is None:
  3850             ctx = repo[None]
  3932             ctx = repo[None]
  3851             parents = ctx.parents()
  3933             parents = ctx.parents()
  3852             taglist = []
  3934             taglist = []
  3853             for p in parents:
  3935             for p in parents:
  3854                 taglist.extend(p.tags())
  3936                 taglist.extend(p.tags())
  3855 
  3937 
  3856             dirty = ""
  3938             dirty = b""
  3857             if ctx.dirty(missing=True, merge=False, branch=False):
  3939             if ctx.dirty(missing=True, merge=False, branch=False):
  3858                 dirty = '+'
  3940                 dirty = b'+'
  3859             fm.data(dirty=dirty)
  3941             fm.data(dirty=dirty)
  3860 
  3942 
  3861             hexoutput = [fm.hexfunc(p.node()) for p in parents]
  3943             hexoutput = [fm.hexfunc(p.node()) for p in parents]
  3862             if default or id:
  3944             if default or id:
  3863                 output = ["%s%s" % ('+'.join(hexoutput), dirty)]
  3945                 output = [b"%s%s" % (b'+'.join(hexoutput), dirty)]
  3864             fm.data(id="%s%s" % ('+'.join(hexoutput), dirty))
  3946             fm.data(id=b"%s%s" % (b'+'.join(hexoutput), dirty))
  3865 
  3947 
  3866             if num:
  3948             if num:
  3867                 numoutput = ["%d" % p.rev() for p in parents]
  3949                 numoutput = [b"%d" % p.rev() for p in parents]
  3868                 output.append("%s%s" % ('+'.join(numoutput), dirty))
  3950                 output.append(b"%s%s" % (b'+'.join(numoutput), dirty))
  3869 
  3951 
  3870             fm.data(
  3952             fm.data(
  3871                 parents=fm.formatlist(
  3953                 parents=fm.formatlist(
  3872                     [fm.hexfunc(p.node()) for p in parents], name='node'
  3954                     [fm.hexfunc(p.node()) for p in parents], name=b'node'
  3873                 )
  3955                 )
  3874             )
  3956             )
  3875         else:
  3957         else:
  3876             hexoutput = fm.hexfunc(ctx.node())
  3958             hexoutput = fm.hexfunc(ctx.node())
  3877             if default or id:
  3959             if default or id:
  3882                 output.append(pycompat.bytestr(ctx.rev()))
  3964                 output.append(pycompat.bytestr(ctx.rev()))
  3883             taglist = ctx.tags()
  3965             taglist = ctx.tags()
  3884 
  3966 
  3885         if default and not ui.quiet:
  3967         if default and not ui.quiet:
  3886             b = ctx.branch()
  3968             b = ctx.branch()
  3887             if b != 'default':
  3969             if b != b'default':
  3888                 output.append("(%s)" % b)
  3970                 output.append(b"(%s)" % b)
  3889 
  3971 
  3890             # multiple tags for a single parent separated by '/'
  3972             # multiple tags for a single parent separated by '/'
  3891             t = '/'.join(taglist)
  3973             t = b'/'.join(taglist)
  3892             if t:
  3974             if t:
  3893                 output.append(t)
  3975                 output.append(t)
  3894 
  3976 
  3895             # multiple bookmarks for a single parent separated by '/'
  3977             # multiple bookmarks for a single parent separated by '/'
  3896             bm = '/'.join(ctx.bookmarks())
  3978             bm = b'/'.join(ctx.bookmarks())
  3897             if bm:
  3979             if bm:
  3898                 output.append(bm)
  3980                 output.append(bm)
  3899         else:
  3981         else:
  3900             if branch:
  3982             if branch:
  3901                 output.append(ctx.branch())
  3983                 output.append(ctx.branch())
  3906             if bookmarks:
  3988             if bookmarks:
  3907                 output.extend(ctx.bookmarks())
  3989                 output.extend(ctx.bookmarks())
  3908 
  3990 
  3909         fm.data(node=ctx.hex())
  3991         fm.data(node=ctx.hex())
  3910         fm.data(branch=ctx.branch())
  3992         fm.data(branch=ctx.branch())
  3911         fm.data(tags=fm.formatlist(taglist, name='tag', sep=':'))
  3993         fm.data(tags=fm.formatlist(taglist, name=b'tag', sep=b':'))
  3912         fm.data(bookmarks=fm.formatlist(ctx.bookmarks(), name='bookmark'))
  3994         fm.data(bookmarks=fm.formatlist(ctx.bookmarks(), name=b'bookmark'))
  3913         fm.context(ctx=ctx)
  3995         fm.context(ctx=ctx)
  3914 
  3996 
  3915     fm.plain("%s\n" % ' '.join(output))
  3997     fm.plain(b"%s\n" % b' '.join(output))
  3916     fm.end()
  3998     fm.end()
  3917 
  3999 
  3918 
  4000 
  3919 @command(
  4001 @command(
  3920     'import|patch',
  4002     b'import|patch',
  3921     [
  4003     [
  3922         (
  4004         (
  3923             'p',
  4005             b'p',
  3924             'strip',
  4006             b'strip',
  3925             1,
  4007             1,
  3926             _(
  4008             _(
  3927                 'directory strip option for patch. This has the same '
  4009                 b'directory strip option for patch. This has the same '
  3928                 'meaning as the corresponding patch option'
  4010                 b'meaning as the corresponding patch option'
  3929             ),
  4011             ),
  3930             _('NUM'),
  4012             _(b'NUM'),
  3931         ),
  4013         ),
  3932         ('b', 'base', '', _('base path (DEPRECATED)'), _('PATH')),
  4014         (b'b', b'base', b'', _(b'base path (DEPRECATED)'), _(b'PATH')),
  3933         ('e', 'edit', False, _('invoke editor on commit messages')),
  4015         (b'e', b'edit', False, _(b'invoke editor on commit messages')),
  3934         (
  4016         (
  3935             'f',
  4017             b'f',
  3936             'force',
  4018             b'force',
  3937             None,
  4019             None,
  3938             _('skip check for outstanding uncommitted changes (DEPRECATED)'),
  4020             _(b'skip check for outstanding uncommitted changes (DEPRECATED)'),
  3939         ),
  4021         ),
  3940         (
  4022         (
  3941             '',
  4023             b'',
  3942             'no-commit',
  4024             b'no-commit',
  3943             None,
  4025             None,
  3944             _("don't commit, just update the working directory"),
  4026             _(b"don't commit, just update the working directory"),
  3945         ),
  4027         ),
  3946         (
  4028         (
  3947             '',
  4029             b'',
  3948             'bypass',
  4030             b'bypass',
  3949             None,
  4031             None,
  3950             _("apply patch without touching the working directory"),
  4032             _(b"apply patch without touching the working directory"),
  3951         ),
  4033         ),
  3952         ('', 'partial', None, _('commit even if some hunks fail')),
  4034         (b'', b'partial', None, _(b'commit even if some hunks fail')),
  3953         ('', 'exact', None, _('abort if patch would apply lossily')),
  4035         (b'', b'exact', None, _(b'abort if patch would apply lossily')),
  3954         ('', 'prefix', '', _('apply patch to subdirectory'), _('DIR')),
  4036         (b'', b'prefix', b'', _(b'apply patch to subdirectory'), _(b'DIR')),
  3955         (
  4037         (
  3956             '',
  4038             b'',
  3957             'import-branch',
  4039             b'import-branch',
  3958             None,
  4040             None,
  3959             _('use any branch information in patch (implied by --exact)'),
  4041             _(b'use any branch information in patch (implied by --exact)'),
  3960         ),
  4042         ),
  3961     ]
  4043     ]
  3962     + commitopts
  4044     + commitopts
  3963     + commitopts2
  4045     + commitopts2
  3964     + similarityopts,
  4046     + similarityopts,
  3965     _('[OPTION]... PATCH...'),
  4047     _(b'[OPTION]... PATCH...'),
  3966     helpcategory=command.CATEGORY_IMPORT_EXPORT,
  4048     helpcategory=command.CATEGORY_IMPORT_EXPORT,
  3967 )
  4049 )
  3968 def import_(ui, repo, patch1=None, *patches, **opts):
  4050 def import_(ui, repo, patch1=None, *patches, **opts):
  3969     """import an ordered set of patches
  4051     """import an ordered set of patches
  3970 
  4052 
  4064     Returns 0 on success, 1 on partial success (see --partial).
  4146     Returns 0 on success, 1 on partial success (see --partial).
  4065     """
  4147     """
  4066 
  4148 
  4067     opts = pycompat.byteskwargs(opts)
  4149     opts = pycompat.byteskwargs(opts)
  4068     if not patch1:
  4150     if not patch1:
  4069         raise error.Abort(_('need at least one patch to import'))
  4151         raise error.Abort(_(b'need at least one patch to import'))
  4070 
  4152 
  4071     patches = (patch1,) + patches
  4153     patches = (patch1,) + patches
  4072 
  4154 
  4073     date = opts.get('date')
  4155     date = opts.get(b'date')
  4074     if date:
  4156     if date:
  4075         opts['date'] = dateutil.parsedate(date)
  4157         opts[b'date'] = dateutil.parsedate(date)
  4076 
  4158 
  4077     exact = opts.get('exact')
  4159     exact = opts.get(b'exact')
  4078     update = not opts.get('bypass')
  4160     update = not opts.get(b'bypass')
  4079     if not update and opts.get('no_commit'):
  4161     if not update and opts.get(b'no_commit'):
  4080         raise error.Abort(_('cannot use --no-commit with --bypass'))
  4162         raise error.Abort(_(b'cannot use --no-commit with --bypass'))
  4081     try:
  4163     try:
  4082         sim = float(opts.get('similarity') or 0)
  4164         sim = float(opts.get(b'similarity') or 0)
  4083     except ValueError:
  4165     except ValueError:
  4084         raise error.Abort(_('similarity must be a number'))
  4166         raise error.Abort(_(b'similarity must be a number'))
  4085     if sim < 0 or sim > 100:
  4167     if sim < 0 or sim > 100:
  4086         raise error.Abort(_('similarity must be between 0 and 100'))
  4168         raise error.Abort(_(b'similarity must be between 0 and 100'))
  4087     if sim and not update:
  4169     if sim and not update:
  4088         raise error.Abort(_('cannot use --similarity with --bypass'))
  4170         raise error.Abort(_(b'cannot use --similarity with --bypass'))
  4089     if exact:
  4171     if exact:
  4090         if opts.get('edit'):
  4172         if opts.get(b'edit'):
  4091             raise error.Abort(_('cannot use --exact with --edit'))
  4173             raise error.Abort(_(b'cannot use --exact with --edit'))
  4092         if opts.get('prefix'):
  4174         if opts.get(b'prefix'):
  4093             raise error.Abort(_('cannot use --exact with --prefix'))
  4175             raise error.Abort(_(b'cannot use --exact with --prefix'))
  4094 
  4176 
  4095     base = opts["base"]
  4177     base = opts[b"base"]
  4096     msgs = []
  4178     msgs = []
  4097     ret = 0
  4179     ret = 0
  4098 
  4180 
  4099     with repo.wlock():
  4181     with repo.wlock():
  4100         if update:
  4182         if update:
  4101             cmdutil.checkunfinished(repo)
  4183             cmdutil.checkunfinished(repo)
  4102             if exact or not opts.get('force'):
  4184             if exact or not opts.get(b'force'):
  4103                 cmdutil.bailifchanged(repo)
  4185                 cmdutil.bailifchanged(repo)
  4104 
  4186 
  4105         if not opts.get('no_commit'):
  4187         if not opts.get(b'no_commit'):
  4106             lock = repo.lock
  4188             lock = repo.lock
  4107             tr = lambda: repo.transaction('import')
  4189             tr = lambda: repo.transaction(b'import')
  4108             dsguard = util.nullcontextmanager
  4190             dsguard = util.nullcontextmanager
  4109         else:
  4191         else:
  4110             lock = util.nullcontextmanager
  4192             lock = util.nullcontextmanager
  4111             tr = util.nullcontextmanager
  4193             tr = util.nullcontextmanager
  4112             dsguard = lambda: dirstateguard.dirstateguard(repo, 'import')
  4194             dsguard = lambda: dirstateguard.dirstateguard(repo, b'import')
  4113         with lock(), tr(), dsguard():
  4195         with lock(), tr(), dsguard():
  4114             parents = repo[None].parents()
  4196             parents = repo[None].parents()
  4115             for patchurl in patches:
  4197             for patchurl in patches:
  4116                 if patchurl == '-':
  4198                 if patchurl == b'-':
  4117                     ui.status(_('applying patch from stdin\n'))
  4199                     ui.status(_(b'applying patch from stdin\n'))
  4118                     patchfile = ui.fin
  4200                     patchfile = ui.fin
  4119                     patchurl = 'stdin'  # for error message
  4201                     patchurl = b'stdin'  # for error message
  4120                 else:
  4202                 else:
  4121                     patchurl = os.path.join(base, patchurl)
  4203                     patchurl = os.path.join(base, patchurl)
  4122                     ui.status(_('applying %s\n') % patchurl)
  4204                     ui.status(_(b'applying %s\n') % patchurl)
  4123                     patchfile = hg.openpath(ui, patchurl, sendaccept=False)
  4205                     patchfile = hg.openpath(ui, patchurl, sendaccept=False)
  4124 
  4206 
  4125                 haspatch = False
  4207                 haspatch = False
  4126                 for hunk in patch.split(patchfile):
  4208                 for hunk in patch.split(patchfile):
  4127                     with patch.extract(ui, hunk) as patchdata:
  4209                     with patch.extract(ui, hunk) as patchdata:
  4128                         msg, node, rej = cmdutil.tryimportone(
  4210                         msg, node, rej = cmdutil.tryimportone(
  4129                             ui, repo, patchdata, parents, opts, msgs, hg.clean
  4211                             ui, repo, patchdata, parents, opts, msgs, hg.clean
  4130                         )
  4212                         )
  4131                     if msg:
  4213                     if msg:
  4132                         haspatch = True
  4214                         haspatch = True
  4133                         ui.note(msg + '\n')
  4215                         ui.note(msg + b'\n')
  4134                     if update or exact:
  4216                     if update or exact:
  4135                         parents = repo[None].parents()
  4217                         parents = repo[None].parents()
  4136                     else:
  4218                     else:
  4137                         parents = [repo[node]]
  4219                         parents = [repo[node]]
  4138                     if rej:
  4220                     if rej:
  4139                         ui.write_err(_("patch applied partially\n"))
  4221                         ui.write_err(_(b"patch applied partially\n"))
  4140                         ui.write_err(
  4222                         ui.write_err(
  4141                             _(
  4223                             _(
  4142                                 "(fix the .rej files and run "
  4224                                 b"(fix the .rej files and run "
  4143                                 "`hg commit --amend`)\n"
  4225                                 b"`hg commit --amend`)\n"
  4144                             )
  4226                             )
  4145                         )
  4227                         )
  4146                         ret = 1
  4228                         ret = 1
  4147                         break
  4229                         break
  4148 
  4230 
  4149                 if not haspatch:
  4231                 if not haspatch:
  4150                     raise error.Abort(_('%s: no diffs found') % patchurl)
  4232                     raise error.Abort(_(b'%s: no diffs found') % patchurl)
  4151 
  4233 
  4152             if msgs:
  4234             if msgs:
  4153                 repo.savecommitmessage('\n* * *\n'.join(msgs))
  4235                 repo.savecommitmessage(b'\n* * *\n'.join(msgs))
  4154         return ret
  4236         return ret
  4155 
  4237 
  4156 
  4238 
  4157 @command(
  4239 @command(
  4158     'incoming|in',
  4240     b'incoming|in',
  4159     [
  4241     [
  4160         ('f', 'force', None, _('run even if remote repository is unrelated')),
  4242         (
  4161         ('n', 'newest-first', None, _('show newest record first')),
  4243             b'f',
  4162         ('', 'bundle', '', _('file to store the bundles into'), _('FILE')),
  4244             b'force',
  4163         (
  4245             None,
  4164             'r',
  4246             _(b'run even if remote repository is unrelated'),
  4165             'rev',
  4247         ),
       
  4248         (b'n', b'newest-first', None, _(b'show newest record first')),
       
  4249         (b'', b'bundle', b'', _(b'file to store the bundles into'), _(b'FILE')),
       
  4250         (
       
  4251             b'r',
       
  4252             b'rev',
  4166             [],
  4253             [],
  4167             _('a remote changeset intended to be added'),
  4254             _(b'a remote changeset intended to be added'),
  4168             _('REV'),
  4255             _(b'REV'),
  4169         ),
  4256         ),
  4170         ('B', 'bookmarks', False, _("compare bookmarks")),
  4257         (b'B', b'bookmarks', False, _(b"compare bookmarks")),
  4171         (
  4258         (
  4172             'b',
  4259             b'b',
  4173             'branch',
  4260             b'branch',
  4174             [],
  4261             [],
  4175             _('a specific branch you would like to pull'),
  4262             _(b'a specific branch you would like to pull'),
  4176             _('BRANCH'),
  4263             _(b'BRANCH'),
  4177         ),
  4264         ),
  4178     ]
  4265     ]
  4179     + logopts
  4266     + logopts
  4180     + remoteopts
  4267     + remoteopts
  4181     + subrepoopts,
  4268     + subrepoopts,
  4182     _('[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'),
  4269     _(b'[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'),
  4183     helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
  4270     helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
  4184 )
  4271 )
  4185 def incoming(ui, repo, source="default", **opts):
  4272 def incoming(ui, repo, source=b"default", **opts):
  4186     """show new changesets found in source
  4273     """show new changesets found in source
  4187 
  4274 
  4188     Show new changesets found in the specified path/URL or the default
  4275     Show new changesets found in the specified path/URL or the default
  4189     pull location. These are the changesets that would have been pulled
  4276     pull location. These are the changesets that would have been pulled
  4190     by :hg:`pull` at the time you issued this command.
  4277     by :hg:`pull` at the time you issued this command.
  4235           hg in changes.hg -T "{desc|firstline}\\n"
  4322           hg in changes.hg -T "{desc|firstline}\\n"
  4236 
  4323 
  4237     Returns 0 if there are incoming changes, 1 otherwise.
  4324     Returns 0 if there are incoming changes, 1 otherwise.
  4238     """
  4325     """
  4239     opts = pycompat.byteskwargs(opts)
  4326     opts = pycompat.byteskwargs(opts)
  4240     if opts.get('graph'):
  4327     if opts.get(b'graph'):
  4241         logcmdutil.checkunsupportedgraphflags([], opts)
  4328         logcmdutil.checkunsupportedgraphflags([], opts)
  4242 
  4329 
  4243         def display(other, chlist, displayer):
  4330         def display(other, chlist, displayer):
  4244             revdag = logcmdutil.graphrevs(other, chlist, opts)
  4331             revdag = logcmdutil.graphrevs(other, chlist, opts)
  4245             logcmdutil.displaygraph(
  4332             logcmdutil.displaygraph(
  4247             )
  4334             )
  4248 
  4335 
  4249         hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
  4336         hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
  4250         return 0
  4337         return 0
  4251 
  4338 
  4252     if opts.get('bundle') and opts.get('subrepos'):
  4339     if opts.get(b'bundle') and opts.get(b'subrepos'):
  4253         raise error.Abort(_('cannot combine --bundle and --subrepos'))
  4340         raise error.Abort(_(b'cannot combine --bundle and --subrepos'))
  4254 
  4341 
  4255     if opts.get('bookmarks'):
  4342     if opts.get(b'bookmarks'):
  4256         source, branches = hg.parseurl(
  4343         source, branches = hg.parseurl(
  4257             ui.expandpath(source), opts.get('branch')
  4344             ui.expandpath(source), opts.get(b'branch')
  4258         )
  4345         )
  4259         other = hg.peer(repo, opts, source)
  4346         other = hg.peer(repo, opts, source)
  4260         if 'bookmarks' not in other.listkeys('namespaces'):
  4347         if b'bookmarks' not in other.listkeys(b'namespaces'):
  4261             ui.warn(_("remote doesn't support bookmarks\n"))
  4348             ui.warn(_(b"remote doesn't support bookmarks\n"))
  4262             return 0
  4349             return 0
  4263         ui.pager('incoming')
  4350         ui.pager(b'incoming')
  4264         ui.status(_('comparing with %s\n') % util.hidepassword(source))
  4351         ui.status(_(b'comparing with %s\n') % util.hidepassword(source))
  4265         return bookmarks.incoming(ui, repo, other)
  4352         return bookmarks.incoming(ui, repo, other)
  4266 
  4353 
  4267     repo._subtoppath = ui.expandpath(source)
  4354     repo._subtoppath = ui.expandpath(source)
  4268     try:
  4355     try:
  4269         return hg.incoming(ui, repo, source, opts)
  4356         return hg.incoming(ui, repo, source, opts)
  4270     finally:
  4357     finally:
  4271         del repo._subtoppath
  4358         del repo._subtoppath
  4272 
  4359 
  4273 
  4360 
  4274 @command(
  4361 @command(
  4275     'init',
  4362     b'init',
  4276     remoteopts,
  4363     remoteopts,
  4277     _('[-e CMD] [--remotecmd CMD] [DEST]'),
  4364     _(b'[-e CMD] [--remotecmd CMD] [DEST]'),
  4278     helpcategory=command.CATEGORY_REPO_CREATION,
  4365     helpcategory=command.CATEGORY_REPO_CREATION,
  4279     helpbasic=True,
  4366     helpbasic=True,
  4280     norepo=True,
  4367     norepo=True,
  4281 )
  4368 )
  4282 def init(ui, dest=".", **opts):
  4369 def init(ui, dest=b".", **opts):
  4283     """create a new repository in the given directory
  4370     """create a new repository in the given directory
  4284 
  4371 
  4285     Initialize a new repository in the given directory. If the given
  4372     Initialize a new repository in the given directory. If the given
  4286     directory does not exist, it will be created.
  4373     directory does not exist, it will be created.
  4287 
  4374 
  4295     opts = pycompat.byteskwargs(opts)
  4382     opts = pycompat.byteskwargs(opts)
  4296     hg.peer(ui, opts, ui.expandpath(dest), create=True)
  4383     hg.peer(ui, opts, ui.expandpath(dest), create=True)
  4297 
  4384 
  4298 
  4385 
  4299 @command(
  4386 @command(
  4300     'locate',
  4387     b'locate',
  4301     [
  4388     [
  4302         ('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
  4389         (
  4303         ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
  4390             b'r',
  4304         (
  4391             b'rev',
  4305             'f',
  4392             b'',
  4306             'fullpath',
  4393             _(b'search the repository as it is in REV'),
       
  4394             _(b'REV'),
       
  4395         ),
       
  4396         (
       
  4397             b'0',
       
  4398             b'print0',
  4307             None,
  4399             None,
  4308             _('print complete paths from the filesystem root'),
  4400             _(b'end filenames with NUL, for use with xargs'),
       
  4401         ),
       
  4402         (
       
  4403             b'f',
       
  4404             b'fullpath',
       
  4405             None,
       
  4406             _(b'print complete paths from the filesystem root'),
  4309         ),
  4407         ),
  4310     ]
  4408     ]
  4311     + walkopts,
  4409     + walkopts,
  4312     _('[OPTION]... [PATTERN]...'),
  4410     _(b'[OPTION]... [PATTERN]...'),
  4313     helpcategory=command.CATEGORY_WORKING_DIRECTORY,
  4411     helpcategory=command.CATEGORY_WORKING_DIRECTORY,
  4314 )
  4412 )
  4315 def locate(ui, repo, *pats, **opts):
  4413 def locate(ui, repo, *pats, **opts):
  4316     """locate files matching specific patterns (DEPRECATED)
  4414     """locate files matching specific patterns (DEPRECATED)
  4317 
  4415 
  4333     See :hg:`help files` for a more versatile command.
  4431     See :hg:`help files` for a more versatile command.
  4334 
  4432 
  4335     Returns 0 if a match is found, 1 otherwise.
  4433     Returns 0 if a match is found, 1 otherwise.
  4336     """
  4434     """
  4337     opts = pycompat.byteskwargs(opts)
  4435     opts = pycompat.byteskwargs(opts)
  4338     if opts.get('print0'):
  4436     if opts.get(b'print0'):
  4339         end = '\0'
  4437         end = b'\0'
  4340     else:
  4438     else:
  4341         end = '\n'
  4439         end = b'\n'
  4342     ctx = scmutil.revsingle(repo, opts.get('rev'), None)
  4440     ctx = scmutil.revsingle(repo, opts.get(b'rev'), None)
  4343 
  4441 
  4344     ret = 1
  4442     ret = 1
  4345     m = scmutil.match(
  4443     m = scmutil.match(
  4346         ctx, pats, opts, default='relglob', badfn=lambda x, y: False
  4444         ctx, pats, opts, default=b'relglob', badfn=lambda x, y: False
  4347     )
  4445     )
  4348 
  4446 
  4349     ui.pager('locate')
  4447     ui.pager(b'locate')
  4350     if ctx.rev() is None:
  4448     if ctx.rev() is None:
  4351         # When run on the working copy, "locate" includes removed files, so
  4449         # When run on the working copy, "locate" includes removed files, so
  4352         # we get the list of files from the dirstate.
  4450         # we get the list of files from the dirstate.
  4353         filesgen = sorted(repo.dirstate.matches(m))
  4451         filesgen = sorted(repo.dirstate.matches(m))
  4354     else:
  4452     else:
  4355         filesgen = ctx.matches(m)
  4453         filesgen = ctx.matches(m)
  4356     uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=bool(pats))
  4454     uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=bool(pats))
  4357     for abs in filesgen:
  4455     for abs in filesgen:
  4358         if opts.get('fullpath'):
  4456         if opts.get(b'fullpath'):
  4359             ui.write(repo.wjoin(abs), end)
  4457             ui.write(repo.wjoin(abs), end)
  4360         else:
  4458         else:
  4361             ui.write(uipathfn(abs), end)
  4459             ui.write(uipathfn(abs), end)
  4362         ret = 0
  4460         ret = 0
  4363 
  4461 
  4364     return ret
  4462     return ret
  4365 
  4463 
  4366 
  4464 
  4367 @command(
  4465 @command(
  4368     'log|history',
  4466     b'log|history',
  4369     [
  4467     [
  4370         (
  4468         (
  4371             'f',
  4469             b'f',
  4372             'follow',
  4470             b'follow',
  4373             None,
  4471             None,
  4374             _(
  4472             _(
  4375                 'follow changeset history, or file history across copies and renames'
  4473                 b'follow changeset history, or file history across copies and renames'
  4376             ),
  4474             ),
  4377         ),
  4475         ),
  4378         (
  4476         (
  4379             '',
  4477             b'',
  4380             'follow-first',
  4478             b'follow-first',
  4381             None,
  4479             None,
  4382             _('only follow the first parent of merge changesets (DEPRECATED)'),
  4480             _(b'only follow the first parent of merge changesets (DEPRECATED)'),
  4383         ),
  4481         ),
  4384         ('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
  4482         (
  4385         ('C', 'copies', None, _('show copied files')),
  4483             b'd',
  4386         (
  4484             b'date',
  4387             'k',
  4485             b'',
  4388             'keyword',
  4486             _(b'show revisions matching date spec'),
       
  4487             _(b'DATE'),
       
  4488         ),
       
  4489         (b'C', b'copies', None, _(b'show copied files')),
       
  4490         (
       
  4491             b'k',
       
  4492             b'keyword',
  4389             [],
  4493             [],
  4390             _('do case-insensitive search for a given text'),
  4494             _(b'do case-insensitive search for a given text'),
  4391             _('TEXT'),
  4495             _(b'TEXT'),
  4392         ),
  4496         ),
  4393         ('r', 'rev', [], _('show the specified revision or revset'), _('REV')),
  4497         (
  4394         (
  4498             b'r',
  4395             'L',
  4499             b'rev',
  4396             'line-range',
       
  4397             [],
  4500             [],
  4398             _('follow line range of specified file (EXPERIMENTAL)'),
  4501             _(b'show the specified revision or revset'),
  4399             _('FILE,RANGE'),
  4502             _(b'REV'),
  4400         ),
  4503         ),
  4401         ('', 'removed', None, _('include revisions where files were removed')),
  4504         (
  4402         (
  4505             b'L',
  4403             'm',
  4506             b'line-range',
  4404             'only-merges',
  4507             [],
       
  4508             _(b'follow line range of specified file (EXPERIMENTAL)'),
       
  4509             _(b'FILE,RANGE'),
       
  4510         ),
       
  4511         (
       
  4512             b'',
       
  4513             b'removed',
  4405             None,
  4514             None,
  4406             _('show only merges (DEPRECATED) (use -r "merge()" instead)'),
  4515             _(b'include revisions where files were removed'),
  4407         ),
  4516         ),
  4408         ('u', 'user', [], _('revisions committed by user'), _('USER')),
  4517         (
  4409         (
  4518             b'm',
  4410             '',
  4519             b'only-merges',
  4411             'only-branch',
  4520             None,
       
  4521             _(b'show only merges (DEPRECATED) (use -r "merge()" instead)'),
       
  4522         ),
       
  4523         (b'u', b'user', [], _(b'revisions committed by user'), _(b'USER')),
       
  4524         (
       
  4525             b'',
       
  4526             b'only-branch',
  4412             [],
  4527             [],
  4413             _(
  4528             _(
  4414                 'show only changesets within the given named branch (DEPRECATED)'
  4529                 b'show only changesets within the given named branch (DEPRECATED)'
  4415             ),
  4530             ),
  4416             _('BRANCH'),
  4531             _(b'BRANCH'),
  4417         ),
  4532         ),
  4418         (
  4533         (
  4419             'b',
  4534             b'b',
  4420             'branch',
  4535             b'branch',
  4421             [],
  4536             [],
  4422             _('show changesets within the given named branch'),
  4537             _(b'show changesets within the given named branch'),
  4423             _('BRANCH'),
  4538             _(b'BRANCH'),
  4424         ),
  4539         ),
  4425         (
  4540         (
  4426             'P',
  4541             b'P',
  4427             'prune',
  4542             b'prune',
  4428             [],
  4543             [],
  4429             _('do not display revision or any of its ancestors'),
  4544             _(b'do not display revision or any of its ancestors'),
  4430             _('REV'),
  4545             _(b'REV'),
  4431         ),
  4546         ),
  4432     ]
  4547     ]
  4433     + logopts
  4548     + logopts
  4434     + walkopts,
  4549     + walkopts,
  4435     _('[OPTION]... [FILE]'),
  4550     _(b'[OPTION]... [FILE]'),
  4436     helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
  4551     helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
  4437     helpbasic=True,
  4552     helpbasic=True,
  4438     inferrepo=True,
  4553     inferrepo=True,
  4439     intents={INTENT_READONLY},
  4554     intents={INTENT_READONLY},
  4440 )
  4555 )
  4565 
  4680 
  4566     Returns 0 on success.
  4681     Returns 0 on success.
  4567 
  4682 
  4568     """
  4683     """
  4569     opts = pycompat.byteskwargs(opts)
  4684     opts = pycompat.byteskwargs(opts)
  4570     linerange = opts.get('line_range')
  4685     linerange = opts.get(b'line_range')
  4571 
  4686 
  4572     if linerange and not opts.get('follow'):
  4687     if linerange and not opts.get(b'follow'):
  4573         raise error.Abort(_('--line-range requires --follow'))
  4688         raise error.Abort(_(b'--line-range requires --follow'))
  4574 
  4689 
  4575     if linerange and pats:
  4690     if linerange and pats:
  4576         # TODO: take pats as patterns with no line-range filter
  4691         # TODO: take pats as patterns with no line-range filter
  4577         raise error.Abort(
  4692         raise error.Abort(
  4578             _('FILE arguments are not compatible with --line-range option')
  4693             _(b'FILE arguments are not compatible with --line-range option')
  4579         )
  4694         )
  4580 
  4695 
  4581     repo = scmutil.unhidehashlikerevs(repo, opts.get('rev'), 'nowarn')
  4696     repo = scmutil.unhidehashlikerevs(repo, opts.get(b'rev'), b'nowarn')
  4582     revs, differ = logcmdutil.getrevs(repo, pats, opts)
  4697     revs, differ = logcmdutil.getrevs(repo, pats, opts)
  4583     if linerange:
  4698     if linerange:
  4584         # TODO: should follow file history from logcmdutil._initialrevs(),
  4699         # TODO: should follow file history from logcmdutil._initialrevs(),
  4585         # then filter the result by logcmdutil._makerevset() and --limit
  4700         # then filter the result by logcmdutil._makerevset() and --limit
  4586         revs, differ = logcmdutil.getlinerangerevs(repo, revs, opts)
  4701         revs, differ = logcmdutil.getlinerangerevs(repo, revs, opts)
  4587 
  4702 
  4588     getcopies = None
  4703     getcopies = None
  4589     if opts.get('copies'):
  4704     if opts.get(b'copies'):
  4590         endrev = None
  4705         endrev = None
  4591         if revs:
  4706         if revs:
  4592             endrev = revs.max() + 1
  4707             endrev = revs.max() + 1
  4593         getcopies = scmutil.getcopiesfn(repo, endrev=endrev)
  4708         getcopies = scmutil.getcopiesfn(repo, endrev=endrev)
  4594 
  4709 
  4595     ui.pager('log')
  4710     ui.pager(b'log')
  4596     displayer = logcmdutil.changesetdisplayer(
  4711     displayer = logcmdutil.changesetdisplayer(
  4597         ui, repo, opts, differ, buffered=True
  4712         ui, repo, opts, differ, buffered=True
  4598     )
  4713     )
  4599     if opts.get('graph'):
  4714     if opts.get(b'graph'):
  4600         displayfn = logcmdutil.displaygraphrevs
  4715         displayfn = logcmdutil.displaygraphrevs
  4601     else:
  4716     else:
  4602         displayfn = logcmdutil.displayrevs
  4717         displayfn = logcmdutil.displayrevs
  4603     displayfn(ui, repo, revs, displayer, getcopies)
  4718     displayfn(ui, repo, revs, displayer, getcopies)
  4604 
  4719 
  4605 
  4720 
  4606 @command(
  4721 @command(
  4607     'manifest',
  4722     b'manifest',
  4608     [
  4723     [
  4609         ('r', 'rev', '', _('revision to display'), _('REV')),
  4724         (b'r', b'rev', b'', _(b'revision to display'), _(b'REV')),
  4610         ('', 'all', False, _("list files from all revisions")),
  4725         (b'', b'all', False, _(b"list files from all revisions")),
  4611     ]
  4726     ]
  4612     + formatteropts,
  4727     + formatteropts,
  4613     _('[-r REV]'),
  4728     _(b'[-r REV]'),
  4614     helpcategory=command.CATEGORY_MAINTENANCE,
  4729     helpcategory=command.CATEGORY_MAINTENANCE,
  4615     intents={INTENT_READONLY},
  4730     intents={INTENT_READONLY},
  4616 )
  4731 )
  4617 def manifest(ui, repo, node=None, rev=None, **opts):
  4732 def manifest(ui, repo, node=None, rev=None, **opts):
  4618     """output the current or given revision of the project manifest
  4733     """output the current or given revision of the project manifest
  4628     is printed. This includes deleted and renamed files.
  4743     is printed. This includes deleted and renamed files.
  4629 
  4744 
  4630     Returns 0 on success.
  4745     Returns 0 on success.
  4631     """
  4746     """
  4632     opts = pycompat.byteskwargs(opts)
  4747     opts = pycompat.byteskwargs(opts)
  4633     fm = ui.formatter('manifest', opts)
  4748     fm = ui.formatter(b'manifest', opts)
  4634 
  4749 
  4635     if opts.get('all'):
  4750     if opts.get(b'all'):
  4636         if rev or node:
  4751         if rev or node:
  4637             raise error.Abort(_("can't specify a revision with --all"))
  4752             raise error.Abort(_(b"can't specify a revision with --all"))
  4638 
  4753 
  4639         res = set()
  4754         res = set()
  4640         for rev in repo:
  4755         for rev in repo:
  4641             ctx = repo[rev]
  4756             ctx = repo[rev]
  4642             res |= set(ctx.files())
  4757             res |= set(ctx.files())
  4643 
  4758 
  4644         ui.pager('manifest')
  4759         ui.pager(b'manifest')
  4645         for f in sorted(res):
  4760         for f in sorted(res):
  4646             fm.startitem()
  4761             fm.startitem()
  4647             fm.write("path", '%s\n', f)
  4762             fm.write(b"path", b'%s\n', f)
  4648         fm.end()
  4763         fm.end()
  4649         return
  4764         return
  4650 
  4765 
  4651     if rev and node:
  4766     if rev and node:
  4652         raise error.Abort(_("please specify just one revision"))
  4767         raise error.Abort(_(b"please specify just one revision"))
  4653 
  4768 
  4654     if not node:
  4769     if not node:
  4655         node = rev
  4770         node = rev
  4656 
  4771 
  4657     char = {'l': '@', 'x': '*', '': '', 't': 'd'}
  4772     char = {b'l': b'@', b'x': b'*', b'': b'', b't': b'd'}
  4658     mode = {'l': '644', 'x': '755', '': '644', 't': '755'}
  4773     mode = {b'l': b'644', b'x': b'755', b'': b'644', b't': b'755'}
  4659     if node:
  4774     if node:
  4660         repo = scmutil.unhidehashlikerevs(repo, [node], 'nowarn')
  4775         repo = scmutil.unhidehashlikerevs(repo, [node], b'nowarn')
  4661     ctx = scmutil.revsingle(repo, node)
  4776     ctx = scmutil.revsingle(repo, node)
  4662     mf = ctx.manifest()
  4777     mf = ctx.manifest()
  4663     ui.pager('manifest')
  4778     ui.pager(b'manifest')
  4664     for f in ctx:
  4779     for f in ctx:
  4665         fm.startitem()
  4780         fm.startitem()
  4666         fm.context(ctx=ctx)
  4781         fm.context(ctx=ctx)
  4667         fl = ctx[f].flags()
  4782         fl = ctx[f].flags()
  4668         fm.condwrite(ui.debugflag, 'hash', '%s ', hex(mf[f]))
  4783         fm.condwrite(ui.debugflag, b'hash', b'%s ', hex(mf[f]))
  4669         fm.condwrite(ui.verbose, 'mode type', '%s %1s ', mode[fl], char[fl])
  4784         fm.condwrite(ui.verbose, b'mode type', b'%s %1s ', mode[fl], char[fl])
  4670         fm.write('path', '%s\n', f)
  4785         fm.write(b'path', b'%s\n', f)
  4671     fm.end()
  4786     fm.end()
  4672 
  4787 
  4673 
  4788 
  4674 @command(
  4789 @command(
  4675     'merge',
  4790     b'merge',
  4676     [
  4791     [
  4677         (
  4792         (
  4678             'f',
  4793             b'f',
  4679             'force',
  4794             b'force',
  4680             None,
  4795             None,
  4681             _('force a merge including outstanding changes (DEPRECATED)'),
  4796             _(b'force a merge including outstanding changes (DEPRECATED)'),
  4682         ),
  4797         ),
  4683         ('r', 'rev', '', _('revision to merge'), _('REV')),
  4798         (b'r', b'rev', b'', _(b'revision to merge'), _(b'REV')),
  4684         (
  4799         (
  4685             'P',
  4800             b'P',
  4686             'preview',
  4801             b'preview',
  4687             None,
  4802             None,
  4688             _('review revisions to merge (no merge is performed)'),
  4803             _(b'review revisions to merge (no merge is performed)'),
  4689         ),
  4804         ),
  4690         ('', 'abort', None, _('abort the ongoing merge')),
  4805         (b'', b'abort', None, _(b'abort the ongoing merge')),
  4691     ]
  4806     ]
  4692     + mergetoolopts,
  4807     + mergetoolopts,
  4693     _('[-P] [[-r] REV]'),
  4808     _(b'[-P] [[-r] REV]'),
  4694     helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
  4809     helpcategory=command.CATEGORY_CHANGE_MANAGEMENT,
  4695     helpbasic=True,
  4810     helpbasic=True,
  4696 )
  4811 )
  4697 def merge(ui, repo, node=None, **opts):
  4812 def merge(ui, repo, node=None, **opts):
  4698     """merge another revision into working directory
  4813     """merge another revision into working directory
  4722 
  4837 
  4723     Returns 0 on success, 1 if there are unresolved files.
  4838     Returns 0 on success, 1 if there are unresolved files.
  4724     """
  4839     """
  4725 
  4840 
  4726     opts = pycompat.byteskwargs(opts)
  4841     opts = pycompat.byteskwargs(opts)
  4727     abort = opts.get('abort')
  4842     abort = opts.get(b'abort')
  4728     if abort and repo.dirstate.p2() == nullid:
  4843     if abort and repo.dirstate.p2() == nullid:
  4729         cmdutil.wrongtooltocontinue(repo, _('merge'))
  4844         cmdutil.wrongtooltocontinue(repo, _(b'merge'))
  4730     if abort:
  4845     if abort:
  4731         state = cmdutil.getunfinishedstate(repo)
  4846         state = cmdutil.getunfinishedstate(repo)
  4732         if state and state._opname != 'merge':
  4847         if state and state._opname != b'merge':
  4733             raise error.Abort(
  4848             raise error.Abort(
  4734                 _('cannot abort merge with %s in progress') % (state._opname),
  4849                 _(b'cannot abort merge with %s in progress') % (state._opname),
  4735                 hint=state.hint(),
  4850                 hint=state.hint(),
  4736             )
  4851             )
  4737         if node:
  4852         if node:
  4738             raise error.Abort(_("cannot specify a node with --abort"))
  4853             raise error.Abort(_(b"cannot specify a node with --abort"))
  4739         if opts.get('rev'):
  4854         if opts.get(b'rev'):
  4740             raise error.Abort(_("cannot specify both --rev and --abort"))
  4855             raise error.Abort(_(b"cannot specify both --rev and --abort"))
  4741         if opts.get('preview'):
  4856         if opts.get(b'preview'):
  4742             raise error.Abort(_("cannot specify --preview with --abort"))
  4857             raise error.Abort(_(b"cannot specify --preview with --abort"))
  4743     if opts.get('rev') and node:
  4858     if opts.get(b'rev') and node:
  4744         raise error.Abort(_("please specify just one revision"))
  4859         raise error.Abort(_(b"please specify just one revision"))
  4745     if not node:
  4860     if not node:
  4746         node = opts.get('rev')
  4861         node = opts.get(b'rev')
  4747 
  4862 
  4748     if node:
  4863     if node:
  4749         node = scmutil.revsingle(repo, node).node()
  4864         node = scmutil.revsingle(repo, node).node()
  4750 
  4865 
  4751     if not node and not abort:
  4866     if not node and not abort:
  4752         node = repo[destutil.destmerge(repo)].node()
  4867         node = repo[destutil.destmerge(repo)].node()
  4753 
  4868 
  4754     if opts.get('preview'):
  4869     if opts.get(b'preview'):
  4755         # find nodes that are ancestors of p2 but not of p1
  4870         # find nodes that are ancestors of p2 but not of p1
  4756         p1 = repo.lookup('.')
  4871         p1 = repo.lookup(b'.')
  4757         p2 = node
  4872         p2 = node
  4758         nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
  4873         nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
  4759 
  4874 
  4760         displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
  4875         displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
  4761         for node in nodes:
  4876         for node in nodes:
  4762             displayer.show(repo[node])
  4877             displayer.show(repo[node])
  4763         displayer.close()
  4878         displayer.close()
  4764         return 0
  4879         return 0
  4765 
  4880 
  4766     # ui.forcemerge is an internal variable, do not document
  4881     # ui.forcemerge is an internal variable, do not document
  4767     overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
  4882     overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
  4768     with ui.configoverride(overrides, 'merge'):
  4883     with ui.configoverride(overrides, b'merge'):
  4769         force = opts.get('force')
  4884         force = opts.get(b'force')
  4770         labels = ['working copy', 'merge rev']
  4885         labels = [b'working copy', b'merge rev']
  4771         return hg.merge(
  4886         return hg.merge(
  4772             repo,
  4887             repo,
  4773             node,
  4888             node,
  4774             force=force,
  4889             force=force,
  4775             mergeforce=force,
  4890             mergeforce=force,
  4777             abort=abort,
  4892             abort=abort,
  4778         )
  4893         )
  4779 
  4894 
  4780 
  4895 
  4781 statemod.addunfinished(
  4896 statemod.addunfinished(
  4782     'merge',
  4897     b'merge',
  4783     fname=None,
  4898     fname=None,
  4784     clearable=True,
  4899     clearable=True,
  4785     allowcommit=True,
  4900     allowcommit=True,
  4786     cmdmsg=_('outstanding uncommitted merge'),
  4901     cmdmsg=_(b'outstanding uncommitted merge'),
  4787     abortfunc=hg.abortmerge,
  4902     abortfunc=hg.abortmerge,
  4788     statushint=_(
  4903     statushint=_(
  4789         'To continue:    hg commit\n' 'To abort:       hg merge --abort'
  4904         b'To continue:    hg commit\n' b'To abort:       hg merge --abort'
  4790     ),
  4905     ),
  4791     cmdhint=_("use 'hg commit' or 'hg merge --abort'"),
  4906     cmdhint=_(b"use 'hg commit' or 'hg merge --abort'"),
  4792 )
  4907 )
  4793 
  4908 
  4794 
  4909 
  4795 @command(
  4910 @command(
  4796     'outgoing|out',
  4911     b'outgoing|out',
  4797     [
  4912     [
  4798         ('f', 'force', None, _('run even when the destination is unrelated')),
  4913         (
  4799         (
  4914             b'f',
  4800             'r',
  4915             b'force',
  4801             'rev',
  4916             None,
       
  4917             _(b'run even when the destination is unrelated'),
       
  4918         ),
       
  4919         (
       
  4920             b'r',
       
  4921             b'rev',
  4802             [],
  4922             [],
  4803             _('a changeset intended to be included in the destination'),
  4923             _(b'a changeset intended to be included in the destination'),
  4804             _('REV'),
  4924             _(b'REV'),
  4805         ),
  4925         ),
  4806         ('n', 'newest-first', None, _('show newest record first')),
  4926         (b'n', b'newest-first', None, _(b'show newest record first')),
  4807         ('B', 'bookmarks', False, _('compare bookmarks')),
  4927         (b'B', b'bookmarks', False, _(b'compare bookmarks')),
  4808         (
  4928         (
  4809             'b',
  4929             b'b',
  4810             'branch',
  4930             b'branch',
  4811             [],
  4931             [],
  4812             _('a specific branch you would like to push'),
  4932             _(b'a specific branch you would like to push'),
  4813             _('BRANCH'),
  4933             _(b'BRANCH'),
  4814         ),
  4934         ),
  4815     ]
  4935     ]
  4816     + logopts
  4936     + logopts
  4817     + remoteopts
  4937     + remoteopts
  4818     + subrepoopts,
  4938     + subrepoopts,
  4819     _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]'),
  4939     _(b'[-M] [-p] [-n] [-f] [-r REV]... [DEST]'),
  4820     helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
  4940     helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
  4821 )
  4941 )
  4822 def outgoing(ui, repo, dest=None, **opts):
  4942 def outgoing(ui, repo, dest=None, **opts):
  4823     """show changesets not found in the destination
  4943     """show changesets not found in the destination
  4824 
  4944 
  4855 
  4975 
  4856     Returns 0 if there are outgoing changes, 1 otherwise.
  4976     Returns 0 if there are outgoing changes, 1 otherwise.
  4857     """
  4977     """
  4858     # hg._outgoing() needs to re-resolve the path in order to handle #branch
  4978     # hg._outgoing() needs to re-resolve the path in order to handle #branch
  4859     # style URLs, so don't overwrite dest.
  4979     # style URLs, so don't overwrite dest.
  4860     path = ui.paths.getpath(dest, default=('default-push', 'default'))
  4980     path = ui.paths.getpath(dest, default=(b'default-push', b'default'))
  4861     if not path:
  4981     if not path:
  4862         raise error.Abort(
  4982         raise error.Abort(
  4863             _('default repository not configured!'),
  4983             _(b'default repository not configured!'),
  4864             hint=_("see 'hg help config.paths'"),
  4984             hint=_(b"see 'hg help config.paths'"),
  4865         )
  4985         )
  4866 
  4986 
  4867     opts = pycompat.byteskwargs(opts)
  4987     opts = pycompat.byteskwargs(opts)
  4868     if opts.get('graph'):
  4988     if opts.get(b'graph'):
  4869         logcmdutil.checkunsupportedgraphflags([], opts)
  4989         logcmdutil.checkunsupportedgraphflags([], opts)
  4870         o, other = hg._outgoing(ui, repo, dest, opts)
  4990         o, other = hg._outgoing(ui, repo, dest, opts)
  4871         if not o:
  4991         if not o:
  4872             cmdutil.outgoinghooks(ui, repo, other, opts, o)
  4992             cmdutil.outgoinghooks(ui, repo, other, opts, o)
  4873             return
  4993             return
  4874 
  4994 
  4875         revdag = logcmdutil.graphrevs(repo, o, opts)
  4995         revdag = logcmdutil.graphrevs(repo, o, opts)
  4876         ui.pager('outgoing')
  4996         ui.pager(b'outgoing')
  4877         displayer = logcmdutil.changesetdisplayer(ui, repo, opts, buffered=True)
  4997         displayer = logcmdutil.changesetdisplayer(ui, repo, opts, buffered=True)
  4878         logcmdutil.displaygraph(
  4998         logcmdutil.displaygraph(
  4879             ui, repo, revdag, displayer, graphmod.asciiedges
  4999             ui, repo, revdag, displayer, graphmod.asciiedges
  4880         )
  5000         )
  4881         cmdutil.outgoinghooks(ui, repo, other, opts, o)
  5001         cmdutil.outgoinghooks(ui, repo, other, opts, o)
  4882         return 0
  5002         return 0
  4883 
  5003 
  4884     if opts.get('bookmarks'):
  5004     if opts.get(b'bookmarks'):
  4885         dest = path.pushloc or path.loc
  5005         dest = path.pushloc or path.loc
  4886         other = hg.peer(repo, opts, dest)
  5006         other = hg.peer(repo, opts, dest)
  4887         if 'bookmarks' not in other.listkeys('namespaces'):
  5007         if b'bookmarks' not in other.listkeys(b'namespaces'):
  4888             ui.warn(_("remote doesn't support bookmarks\n"))
  5008             ui.warn(_(b"remote doesn't support bookmarks\n"))
  4889             return 0
  5009             return 0
  4890         ui.status(_('comparing with %s\n') % util.hidepassword(dest))
  5010         ui.status(_(b'comparing with %s\n') % util.hidepassword(dest))
  4891         ui.pager('outgoing')
  5011         ui.pager(b'outgoing')
  4892         return bookmarks.outgoing(ui, repo, other)
  5012         return bookmarks.outgoing(ui, repo, other)
  4893 
  5013 
  4894     repo._subtoppath = path.pushloc or path.loc
  5014     repo._subtoppath = path.pushloc or path.loc
  4895     try:
  5015     try:
  4896         return hg.outgoing(ui, repo, dest, opts)
  5016         return hg.outgoing(ui, repo, dest, opts)
  4897     finally:
  5017     finally:
  4898         del repo._subtoppath
  5018         del repo._subtoppath
  4899 
  5019 
  4900 
  5020 
  4901 @command(
  5021 @command(
  4902     'parents',
  5022     b'parents',
  4903     [('r', 'rev', '', _('show parents of the specified revision'), _('REV')),]
  5023     [
       
  5024         (
       
  5025             b'r',
       
  5026             b'rev',
       
  5027             b'',
       
  5028             _(b'show parents of the specified revision'),
       
  5029             _(b'REV'),
       
  5030         ),
       
  5031     ]
  4904     + templateopts,
  5032     + templateopts,
  4905     _('[-r REV] [FILE]'),
  5033     _(b'[-r REV] [FILE]'),
  4906     helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
  5034     helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
  4907     inferrepo=True,
  5035     inferrepo=True,
  4908 )
  5036 )
  4909 def parents(ui, repo, file_=None, **opts):
  5037 def parents(ui, repo, file_=None, **opts):
  4910     """show the parents of the working directory or revision (DEPRECATED)
  5038     """show the parents of the working directory or revision (DEPRECATED)
  4926 
  5054 
  4927     Returns 0 on success.
  5055     Returns 0 on success.
  4928     """
  5056     """
  4929 
  5057 
  4930     opts = pycompat.byteskwargs(opts)
  5058     opts = pycompat.byteskwargs(opts)
  4931     rev = opts.get('rev')
  5059     rev = opts.get(b'rev')
  4932     if rev:
  5060     if rev:
  4933         repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
  5061         repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
  4934     ctx = scmutil.revsingle(repo, rev, None)
  5062     ctx = scmutil.revsingle(repo, rev, None)
  4935 
  5063 
  4936     if file_:
  5064     if file_:
  4937         m = scmutil.match(ctx, (file_,), opts)
  5065         m = scmutil.match(ctx, (file_,), opts)
  4938         if m.anypats() or len(m.files()) != 1:
  5066         if m.anypats() or len(m.files()) != 1:
  4939             raise error.Abort(_('can only specify an explicit filename'))
  5067             raise error.Abort(_(b'can only specify an explicit filename'))
  4940         file_ = m.files()[0]
  5068         file_ = m.files()[0]
  4941         filenodes = []
  5069         filenodes = []
  4942         for cp in ctx.parents():
  5070         for cp in ctx.parents():
  4943             if not cp:
  5071             if not cp:
  4944                 continue
  5072                 continue
  4945             try:
  5073             try:
  4946                 filenodes.append(cp.filenode(file_))
  5074                 filenodes.append(cp.filenode(file_))
  4947             except error.LookupError:
  5075             except error.LookupError:
  4948                 pass
  5076                 pass
  4949         if not filenodes:
  5077         if not filenodes:
  4950             raise error.Abort(_("'%s' not found in manifest!") % file_)
  5078             raise error.Abort(_(b"'%s' not found in manifest!") % file_)
  4951         p = []
  5079         p = []
  4952         for fn in filenodes:
  5080         for fn in filenodes:
  4953             fctx = repo.filectx(file_, fileid=fn)
  5081             fctx = repo.filectx(file_, fileid=fn)
  4954             p.append(fctx.node())
  5082             p.append(fctx.node())
  4955     else:
  5083     else:
  4961             displayer.show(repo[n])
  5089             displayer.show(repo[n])
  4962     displayer.close()
  5090     displayer.close()
  4963 
  5091 
  4964 
  5092 
  4965 @command(
  5093 @command(
  4966     'paths',
  5094     b'paths',
  4967     formatteropts,
  5095     formatteropts,
  4968     _('[NAME]'),
  5096     _(b'[NAME]'),
  4969     helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
  5097     helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
  4970     optionalrepo=True,
  5098     optionalrepo=True,
  4971     intents={INTENT_READONLY},
  5099     intents={INTENT_READONLY},
  4972 )
  5100 )
  4973 def paths(ui, repo, search=None, **opts):
  5101 def paths(ui, repo, search=None, **opts):
  5011 
  5139 
  5012     Returns 0 on success.
  5140     Returns 0 on success.
  5013     """
  5141     """
  5014 
  5142 
  5015     opts = pycompat.byteskwargs(opts)
  5143     opts = pycompat.byteskwargs(opts)
  5016     ui.pager('paths')
  5144     ui.pager(b'paths')
  5017     if search:
  5145     if search:
  5018         pathitems = [
  5146         pathitems = [
  5019             (name, path)
  5147             (name, path)
  5020             for name, path in ui.paths.iteritems()
  5148             for name, path in ui.paths.iteritems()
  5021             if name == search
  5149             if name == search
  5022         ]
  5150         ]
  5023     else:
  5151     else:
  5024         pathitems = sorted(ui.paths.iteritems())
  5152         pathitems = sorted(ui.paths.iteritems())
  5025 
  5153 
  5026     fm = ui.formatter('paths', opts)
  5154     fm = ui.formatter(b'paths', opts)
  5027     if fm.isplain():
  5155     if fm.isplain():
  5028         hidepassword = util.hidepassword
  5156         hidepassword = util.hidepassword
  5029     else:
  5157     else:
  5030         hidepassword = bytes
  5158         hidepassword = bytes
  5031     if ui.quiet:
  5159     if ui.quiet:
  5032         namefmt = '%s\n'
  5160         namefmt = b'%s\n'
  5033     else:
  5161     else:
  5034         namefmt = '%s = '
  5162         namefmt = b'%s = '
  5035     showsubopts = not search and not ui.quiet
  5163     showsubopts = not search and not ui.quiet
  5036 
  5164 
  5037     for name, path in pathitems:
  5165     for name, path in pathitems:
  5038         fm.startitem()
  5166         fm.startitem()
  5039         fm.condwrite(not search, 'name', namefmt, name)
  5167         fm.condwrite(not search, b'name', namefmt, name)
  5040         fm.condwrite(not ui.quiet, 'url', '%s\n', hidepassword(path.rawloc))
  5168         fm.condwrite(not ui.quiet, b'url', b'%s\n', hidepassword(path.rawloc))
  5041         for subopt, value in sorted(path.suboptions.items()):
  5169         for subopt, value in sorted(path.suboptions.items()):
  5042             assert subopt not in ('name', 'url')
  5170             assert subopt not in (b'name', b'url')
  5043             if showsubopts:
  5171             if showsubopts:
  5044                 fm.plain('%s:%s = ' % (name, subopt))
  5172                 fm.plain(b'%s:%s = ' % (name, subopt))
  5045             fm.condwrite(showsubopts, subopt, '%s\n', value)
  5173             fm.condwrite(showsubopts, subopt, b'%s\n', value)
  5046 
  5174 
  5047     fm.end()
  5175     fm.end()
  5048 
  5176 
  5049     if search and not pathitems:
  5177     if search and not pathitems:
  5050         if not ui.quiet:
  5178         if not ui.quiet:
  5051             ui.warn(_("not found!\n"))
  5179             ui.warn(_(b"not found!\n"))
  5052         return 1
  5180         return 1
  5053     else:
  5181     else:
  5054         return 0
  5182         return 0
  5055 
  5183 
  5056 
  5184 
  5057 @command(
  5185 @command(
  5058     'phase',
  5186     b'phase',
  5059     [
  5187     [
  5060         ('p', 'public', False, _('set changeset phase to public')),
  5188         (b'p', b'public', False, _(b'set changeset phase to public')),
  5061         ('d', 'draft', False, _('set changeset phase to draft')),
  5189         (b'd', b'draft', False, _(b'set changeset phase to draft')),
  5062         ('s', 'secret', False, _('set changeset phase to secret')),
  5190         (b's', b'secret', False, _(b'set changeset phase to secret')),
  5063         ('f', 'force', False, _('allow to move boundary backward')),
  5191         (b'f', b'force', False, _(b'allow to move boundary backward')),
  5064         ('r', 'rev', [], _('target revision'), _('REV')),
  5192         (b'r', b'rev', [], _(b'target revision'), _(b'REV')),
  5065     ],
  5193     ],
  5066     _('[-p|-d|-s] [-f] [-r] [REV...]'),
  5194     _(b'[-p|-d|-s] [-f] [-r] [REV...]'),
  5067     helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
  5195     helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
  5068 )
  5196 )
  5069 def phase(ui, repo, *revs, **opts):
  5197 def phase(ui, repo, *revs, **opts):
  5070     """set or show the current phase name
  5198     """set or show the current phase name
  5071 
  5199 
  5087     # search for a unique phase argument
  5215     # search for a unique phase argument
  5088     targetphase = None
  5216     targetphase = None
  5089     for idx, name in enumerate(phases.cmdphasenames):
  5217     for idx, name in enumerate(phases.cmdphasenames):
  5090         if opts[name]:
  5218         if opts[name]:
  5091             if targetphase is not None:
  5219             if targetphase is not None:
  5092                 raise error.Abort(_('only one phase can be specified'))
  5220                 raise error.Abort(_(b'only one phase can be specified'))
  5093             targetphase = idx
  5221             targetphase = idx
  5094 
  5222 
  5095     # look for specified revision
  5223     # look for specified revision
  5096     revs = list(revs)
  5224     revs = list(revs)
  5097     revs.extend(opts['rev'])
  5225     revs.extend(opts[b'rev'])
  5098     if not revs:
  5226     if not revs:
  5099         # display both parents as the second parent phase can influence
  5227         # display both parents as the second parent phase can influence
  5100         # the phase of a merge commit
  5228         # the phase of a merge commit
  5101         revs = [c.rev() for c in repo[None].parents()]
  5229         revs = [c.rev() for c in repo[None].parents()]
  5102 
  5230 
  5105     ret = 0
  5233     ret = 0
  5106     if targetphase is None:
  5234     if targetphase is None:
  5107         # display
  5235         # display
  5108         for r in revs:
  5236         for r in revs:
  5109             ctx = repo[r]
  5237             ctx = repo[r]
  5110             ui.write('%i: %s\n' % (ctx.rev(), ctx.phasestr()))
  5238             ui.write(b'%i: %s\n' % (ctx.rev(), ctx.phasestr()))
  5111     else:
  5239     else:
  5112         with repo.lock(), repo.transaction("phase") as tr:
  5240         with repo.lock(), repo.transaction(b"phase") as tr:
  5113             # set phase
  5241             # set phase
  5114             if not revs:
  5242             if not revs:
  5115                 raise error.Abort(_('empty revision set'))
  5243                 raise error.Abort(_(b'empty revision set'))
  5116             nodes = [repo[r].node() for r in revs]
  5244             nodes = [repo[r].node() for r in revs]
  5117             # moving revision from public to draft may hide them
  5245             # moving revision from public to draft may hide them
  5118             # We have to check result on an unfiltered repository
  5246             # We have to check result on an unfiltered repository
  5119             unfi = repo.unfiltered()
  5247             unfi = repo.unfiltered()
  5120             getphase = unfi._phasecache.phase
  5248             getphase = unfi._phasecache.phase
  5121             olddata = [getphase(unfi, r) for r in unfi]
  5249             olddata = [getphase(unfi, r) for r in unfi]
  5122             phases.advanceboundary(repo, tr, targetphase, nodes)
  5250             phases.advanceboundary(repo, tr, targetphase, nodes)
  5123             if opts['force']:
  5251             if opts[b'force']:
  5124                 phases.retractboundary(repo, tr, targetphase, nodes)
  5252                 phases.retractboundary(repo, tr, targetphase, nodes)
  5125         getphase = unfi._phasecache.phase
  5253         getphase = unfi._phasecache.phase
  5126         newdata = [getphase(unfi, r) for r in unfi]
  5254         newdata = [getphase(unfi, r) for r in unfi]
  5127         changes = sum(newdata[r] != olddata[r] for r in unfi)
  5255         changes = sum(newdata[r] != olddata[r] for r in unfi)
  5128         cl = unfi.changelog
  5256         cl = unfi.changelog
  5129         rejected = [n for n in nodes if newdata[cl.rev(n)] < targetphase]
  5257         rejected = [n for n in nodes if newdata[cl.rev(n)] < targetphase]
  5130         if rejected:
  5258         if rejected:
  5131             ui.warn(
  5259             ui.warn(
  5132                 _(
  5260                 _(
  5133                     'cannot move %i changesets to a higher '
  5261                     b'cannot move %i changesets to a higher '
  5134                     'phase, use --force\n'
  5262                     b'phase, use --force\n'
  5135                 )
  5263                 )
  5136                 % len(rejected)
  5264                 % len(rejected)
  5137             )
  5265             )
  5138             ret = 1
  5266             ret = 1
  5139         if changes:
  5267         if changes:
  5140             msg = _('phase changed for %i changesets\n') % changes
  5268             msg = _(b'phase changed for %i changesets\n') % changes
  5141             if ret:
  5269             if ret:
  5142                 ui.status(msg)
  5270                 ui.status(msg)
  5143             else:
  5271             else:
  5144                 ui.note(msg)
  5272                 ui.note(msg)
  5145         else:
  5273         else:
  5146             ui.warn(_('no phases changed\n'))
  5274             ui.warn(_(b'no phases changed\n'))
  5147     return ret
  5275     return ret
  5148 
  5276 
  5149 
  5277 
  5150 def postincoming(ui, repo, modheads, optupdate, checkout, brev):
  5278 def postincoming(ui, repo, modheads, optupdate, checkout, brev):
  5151     """Run after a changegroup has been added via pull/unbundle
  5279     """Run after a changegroup has been added via pull/unbundle
  5161         return
  5289         return
  5162     if optupdate:
  5290     if optupdate:
  5163         try:
  5291         try:
  5164             return hg.updatetotally(ui, repo, checkout, brev)
  5292             return hg.updatetotally(ui, repo, checkout, brev)
  5165         except error.UpdateAbort as inst:
  5293         except error.UpdateAbort as inst:
  5166             msg = _("not updating: %s") % stringutil.forcebytestr(inst)
  5294             msg = _(b"not updating: %s") % stringutil.forcebytestr(inst)
  5167             hint = inst.hint
  5295             hint = inst.hint
  5168             raise error.UpdateAbort(msg, hint=hint)
  5296             raise error.UpdateAbort(msg, hint=hint)
  5169     if modheads is not None and modheads > 1:
  5297     if modheads is not None and modheads > 1:
  5170         currentbranchheads = len(repo.branchheads())
  5298         currentbranchheads = len(repo.branchheads())
  5171         if currentbranchheads == modheads:
  5299         if currentbranchheads == modheads:
  5172             ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
  5300             ui.status(
       
  5301                 _(b"(run 'hg heads' to see heads, 'hg merge' to merge)\n")
       
  5302             )
  5173         elif currentbranchheads > 1:
  5303         elif currentbranchheads > 1:
  5174             ui.status(
  5304             ui.status(
  5175                 _("(run 'hg heads .' to see heads, 'hg merge' to " "merge)\n")
  5305                 _(b"(run 'hg heads .' to see heads, 'hg merge' to " b"merge)\n")
  5176             )
  5306             )
  5177         else:
  5307         else:
  5178             ui.status(_("(run 'hg heads' to see heads)\n"))
  5308             ui.status(_(b"(run 'hg heads' to see heads)\n"))
  5179     elif not ui.configbool('commands', 'update.requiredest'):
  5309     elif not ui.configbool(b'commands', b'update.requiredest'):
  5180         ui.status(_("(run 'hg update' to get a working copy)\n"))
  5310         ui.status(_(b"(run 'hg update' to get a working copy)\n"))
  5181 
  5311 
  5182 
  5312 
  5183 @command(
  5313 @command(
  5184     'pull',
  5314     b'pull',
  5185     [
  5315     [
  5186         (
  5316         (
  5187             'u',
  5317             b'u',
  5188             'update',
  5318             b'update',
  5189             None,
  5319             None,
  5190             _('update to new branch head if new descendants were pulled'),
  5320             _(b'update to new branch head if new descendants were pulled'),
  5191         ),
  5321         ),
  5192         ('f', 'force', None, _('run even when remote repository is unrelated')),
  5322         (
  5193         (
  5323             b'f',
  5194             'r',
  5324             b'force',
  5195             'rev',
  5325             None,
       
  5326             _(b'run even when remote repository is unrelated'),
       
  5327         ),
       
  5328         (
       
  5329             b'r',
       
  5330             b'rev',
  5196             [],
  5331             [],
  5197             _('a remote changeset intended to be added'),
  5332             _(b'a remote changeset intended to be added'),
  5198             _('REV'),
  5333             _(b'REV'),
  5199         ),
  5334         ),
  5200         ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
  5335         (b'B', b'bookmark', [], _(b"bookmark to pull"), _(b'BOOKMARK')),
  5201         (
  5336         (
  5202             'b',
  5337             b'b',
  5203             'branch',
  5338             b'branch',
  5204             [],
  5339             [],
  5205             _('a specific branch you would like to pull'),
  5340             _(b'a specific branch you would like to pull'),
  5206             _('BRANCH'),
  5341             _(b'BRANCH'),
  5207         ),
  5342         ),
  5208     ]
  5343     ]
  5209     + remoteopts,
  5344     + remoteopts,
  5210     _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'),
  5345     _(b'[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'),
  5211     helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
  5346     helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
  5212     helpbasic=True,
  5347     helpbasic=True,
  5213 )
  5348 )
  5214 def pull(ui, repo, source="default", **opts):
  5349 def pull(ui, repo, source=b"default", **opts):
  5215     """pull changes from the specified source
  5350     """pull changes from the specified source
  5216 
  5351 
  5217     Pull changes from a remote repository to a local one.
  5352     Pull changes from a remote repository to a local one.
  5218 
  5353 
  5219     This finds all changes from the repository at the specified path
  5354     This finds all changes from the repository at the specified path
  5240 
  5375 
  5241     Returns 0 on success, 1 if an update had unresolved files.
  5376     Returns 0 on success, 1 if an update had unresolved files.
  5242     """
  5377     """
  5243 
  5378 
  5244     opts = pycompat.byteskwargs(opts)
  5379     opts = pycompat.byteskwargs(opts)
  5245     if ui.configbool('commands', 'update.requiredest') and opts.get('update'):
  5380     if ui.configbool(b'commands', b'update.requiredest') and opts.get(
  5246         msg = _('update destination required by configuration')
  5381         b'update'
  5247         hint = _('use hg pull followed by hg update DEST')
  5382     ):
       
  5383         msg = _(b'update destination required by configuration')
       
  5384         hint = _(b'use hg pull followed by hg update DEST')
  5248         raise error.Abort(msg, hint=hint)
  5385         raise error.Abort(msg, hint=hint)
  5249 
  5386 
  5250     source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
  5387     source, branches = hg.parseurl(ui.expandpath(source), opts.get(b'branch'))
  5251     ui.status(_('pulling from %s\n') % util.hidepassword(source))
  5388     ui.status(_(b'pulling from %s\n') % util.hidepassword(source))
  5252     other = hg.peer(repo, opts, source)
  5389     other = hg.peer(repo, opts, source)
  5253     try:
  5390     try:
  5254         revs, checkout = hg.addbranchrevs(
  5391         revs, checkout = hg.addbranchrevs(
  5255             repo, other, branches, opts.get('rev')
  5392             repo, other, branches, opts.get(b'rev')
  5256         )
  5393         )
  5257 
  5394 
  5258         pullopargs = {}
  5395         pullopargs = {}
  5259 
  5396 
  5260         nodes = None
  5397         nodes = None
  5261         if opts.get('bookmark') or revs:
  5398         if opts.get(b'bookmark') or revs:
  5262             # The list of bookmark used here is the same used to actually update
  5399             # The list of bookmark used here is the same used to actually update
  5263             # the bookmark names, to avoid the race from issue 4689 and we do
  5400             # the bookmark names, to avoid the race from issue 4689 and we do
  5264             # all lookup and bookmark queries in one go so they see the same
  5401             # all lookup and bookmark queries in one go so they see the same
  5265             # version of the server state (issue 4700).
  5402             # version of the server state (issue 4700).
  5266             nodes = []
  5403             nodes = []
  5267             fnodes = []
  5404             fnodes = []
  5268             revs = revs or []
  5405             revs = revs or []
  5269             if revs and not other.capable('lookup'):
  5406             if revs and not other.capable(b'lookup'):
  5270                 err = _(
  5407                 err = _(
  5271                     "other repository doesn't support revision lookup, "
  5408                     b"other repository doesn't support revision lookup, "
  5272                     "so a rev cannot be specified."
  5409                     b"so a rev cannot be specified."
  5273                 )
  5410                 )
  5274                 raise error.Abort(err)
  5411                 raise error.Abort(err)
  5275             with other.commandexecutor() as e:
  5412             with other.commandexecutor() as e:
  5276                 fremotebookmarks = e.callcommand(
  5413                 fremotebookmarks = e.callcommand(
  5277                     'listkeys', {'namespace': 'bookmarks'}
  5414                     b'listkeys', {b'namespace': b'bookmarks'}
  5278                 )
  5415                 )
  5279                 for r in revs:
  5416                 for r in revs:
  5280                     fnodes.append(e.callcommand('lookup', {'key': r}))
  5417                     fnodes.append(e.callcommand(b'lookup', {b'key': r}))
  5281             remotebookmarks = fremotebookmarks.result()
  5418             remotebookmarks = fremotebookmarks.result()
  5282             remotebookmarks = bookmarks.unhexlifybookmarks(remotebookmarks)
  5419             remotebookmarks = bookmarks.unhexlifybookmarks(remotebookmarks)
  5283             pullopargs['remotebookmarks'] = remotebookmarks
  5420             pullopargs[b'remotebookmarks'] = remotebookmarks
  5284             for b in opts.get('bookmark', []):
  5421             for b in opts.get(b'bookmark', []):
  5285                 b = repo._bookmarks.expandname(b)
  5422                 b = repo._bookmarks.expandname(b)
  5286                 if b not in remotebookmarks:
  5423                 if b not in remotebookmarks:
  5287                     raise error.Abort(_('remote bookmark %s not found!') % b)
  5424                     raise error.Abort(_(b'remote bookmark %s not found!') % b)
  5288                 nodes.append(remotebookmarks[b])
  5425                 nodes.append(remotebookmarks[b])
  5289             for i, rev in enumerate(revs):
  5426             for i, rev in enumerate(revs):
  5290                 node = fnodes[i].result()
  5427                 node = fnodes[i].result()
  5291                 nodes.append(node)
  5428                 nodes.append(node)
  5292                 if rev == checkout:
  5429                 if rev == checkout:
  5293                     checkout = node
  5430                     checkout = node
  5294 
  5431 
  5295         wlock = util.nullcontextmanager()
  5432         wlock = util.nullcontextmanager()
  5296         if opts.get('update'):
  5433         if opts.get(b'update'):
  5297             wlock = repo.wlock()
  5434             wlock = repo.wlock()
  5298         with wlock:
  5435         with wlock:
  5299             pullopargs.update(opts.get('opargs', {}))
  5436             pullopargs.update(opts.get(b'opargs', {}))
  5300             modheads = exchange.pull(
  5437             modheads = exchange.pull(
  5301                 repo,
  5438                 repo,
  5302                 other,
  5439                 other,
  5303                 heads=nodes,
  5440                 heads=nodes,
  5304                 force=opts.get('force'),
  5441                 force=opts.get(b'force'),
  5305                 bookmarks=opts.get('bookmark', ()),
  5442                 bookmarks=opts.get(b'bookmark', ()),
  5306                 opargs=pullopargs,
  5443                 opargs=pullopargs,
  5307             ).cgresult
  5444             ).cgresult
  5308 
  5445 
  5309             # brev is a name, which might be a bookmark to be activated at
  5446             # brev is a name, which might be a bookmark to be activated at
  5310             # the end of the update. In other words, it is an explicit
  5447             # the end of the update. In other words, it is an explicit
  5315                 checkout = repo.unfiltered().changelog.rev(checkout)
  5452                 checkout = repo.unfiltered().changelog.rev(checkout)
  5316 
  5453 
  5317                 # order below depends on implementation of
  5454                 # order below depends on implementation of
  5318                 # hg.addbranchrevs(). opts['bookmark'] is ignored,
  5455                 # hg.addbranchrevs(). opts['bookmark'] is ignored,
  5319                 # because 'checkout' is determined without it.
  5456                 # because 'checkout' is determined without it.
  5320                 if opts.get('rev'):
  5457                 if opts.get(b'rev'):
  5321                     brev = opts['rev'][0]
  5458                     brev = opts[b'rev'][0]
  5322                 elif opts.get('branch'):
  5459                 elif opts.get(b'branch'):
  5323                     brev = opts['branch'][0]
  5460                     brev = opts[b'branch'][0]
  5324                 else:
  5461                 else:
  5325                     brev = branches[0]
  5462                     brev = branches[0]
  5326             repo._subtoppath = source
  5463             repo._subtoppath = source
  5327             try:
  5464             try:
  5328                 ret = postincoming(
  5465                 ret = postincoming(
  5329                     ui, repo, modheads, opts.get('update'), checkout, brev
  5466                     ui, repo, modheads, opts.get(b'update'), checkout, brev
  5330                 )
  5467                 )
  5331             except error.FilteredRepoLookupError as exc:
  5468             except error.FilteredRepoLookupError as exc:
  5332                 msg = _('cannot update to target: %s') % exc.args[0]
  5469                 msg = _(b'cannot update to target: %s') % exc.args[0]
  5333                 exc.args = (msg,) + exc.args[1:]
  5470                 exc.args = (msg,) + exc.args[1:]
  5334                 raise
  5471                 raise
  5335             finally:
  5472             finally:
  5336                 del repo._subtoppath
  5473                 del repo._subtoppath
  5337 
  5474 
  5339         other.close()
  5476         other.close()
  5340     return ret
  5477     return ret
  5341 
  5478 
  5342 
  5479 
  5343 @command(
  5480 @command(
  5344     'push',
  5481     b'push',
  5345     [
  5482     [
  5346         ('f', 'force', None, _('force push')),
  5483         (b'f', b'force', None, _(b'force push')),
  5347         (
  5484         (
  5348             'r',
  5485             b'r',
  5349             'rev',
  5486             b'rev',
  5350             [],
  5487             [],
  5351             _('a changeset intended to be included in the destination'),
  5488             _(b'a changeset intended to be included in the destination'),
  5352             _('REV'),
  5489             _(b'REV'),
  5353         ),
  5490         ),
  5354         ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
  5491         (b'B', b'bookmark', [], _(b"bookmark to push"), _(b'BOOKMARK')),
  5355         (
  5492         (
  5356             'b',
  5493             b'b',
  5357             'branch',
  5494             b'branch',
  5358             [],
  5495             [],
  5359             _('a specific branch you would like to push'),
  5496             _(b'a specific branch you would like to push'),
  5360             _('BRANCH'),
  5497             _(b'BRANCH'),
  5361         ),
  5498         ),
  5362         ('', 'new-branch', False, _('allow pushing a new branch')),
  5499         (b'', b'new-branch', False, _(b'allow pushing a new branch')),
  5363         (
  5500         (
  5364             '',
  5501             b'',
  5365             'pushvars',
  5502             b'pushvars',
  5366             [],
  5503             [],
  5367             _('variables that can be sent to server (ADVANCED)'),
  5504             _(b'variables that can be sent to server (ADVANCED)'),
  5368         ),
  5505         ),
  5369         (
  5506         (
  5370             '',
  5507             b'',
  5371             'publish',
  5508             b'publish',
  5372             False,
  5509             False,
  5373             _('push the changeset as public (EXPERIMENTAL)'),
  5510             _(b'push the changeset as public (EXPERIMENTAL)'),
  5374         ),
  5511         ),
  5375     ]
  5512     ]
  5376     + remoteopts,
  5513     + remoteopts,
  5377     _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'),
  5514     _(b'[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'),
  5378     helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
  5515     helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
  5379     helpbasic=True,
  5516     helpbasic=True,
  5380 )
  5517 )
  5381 def push(ui, repo, dest=None, **opts):
  5518 def push(ui, repo, dest=None, **opts):
  5382     """push changes to the specified destination
  5519     """push changes to the specified destination
  5434 
  5571 
  5435     Returns 0 if push was successful, 1 if nothing to push.
  5572     Returns 0 if push was successful, 1 if nothing to push.
  5436     """
  5573     """
  5437 
  5574 
  5438     opts = pycompat.byteskwargs(opts)
  5575     opts = pycompat.byteskwargs(opts)
  5439     if opts.get('bookmark'):
  5576     if opts.get(b'bookmark'):
  5440         ui.setconfig('bookmarks', 'pushing', opts['bookmark'], 'push')
  5577         ui.setconfig(b'bookmarks', b'pushing', opts[b'bookmark'], b'push')
  5441         for b in opts['bookmark']:
  5578         for b in opts[b'bookmark']:
  5442             # translate -B options to -r so changesets get pushed
  5579             # translate -B options to -r so changesets get pushed
  5443             b = repo._bookmarks.expandname(b)
  5580             b = repo._bookmarks.expandname(b)
  5444             if b in repo._bookmarks:
  5581             if b in repo._bookmarks:
  5445                 opts.setdefault('rev', []).append(b)
  5582                 opts.setdefault(b'rev', []).append(b)
  5446             else:
  5583             else:
  5447                 # if we try to push a deleted bookmark, translate it to null
  5584                 # if we try to push a deleted bookmark, translate it to null
  5448                 # this lets simultaneous -r, -b options continue working
  5585                 # this lets simultaneous -r, -b options continue working
  5449                 opts.setdefault('rev', []).append("null")
  5586                 opts.setdefault(b'rev', []).append(b"null")
  5450 
  5587 
  5451     path = ui.paths.getpath(dest, default=('default-push', 'default'))
  5588     path = ui.paths.getpath(dest, default=(b'default-push', b'default'))
  5452     if not path:
  5589     if not path:
  5453         raise error.Abort(
  5590         raise error.Abort(
  5454             _('default repository not configured!'),
  5591             _(b'default repository not configured!'),
  5455             hint=_("see 'hg help config.paths'"),
  5592             hint=_(b"see 'hg help config.paths'"),
  5456         )
  5593         )
  5457     dest = path.pushloc or path.loc
  5594     dest = path.pushloc or path.loc
  5458     branches = (path.branch, opts.get('branch') or [])
  5595     branches = (path.branch, opts.get(b'branch') or [])
  5459     ui.status(_('pushing to %s\n') % util.hidepassword(dest))
  5596     ui.status(_(b'pushing to %s\n') % util.hidepassword(dest))
  5460     revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
  5597     revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get(b'rev'))
  5461     other = hg.peer(repo, opts, dest)
  5598     other = hg.peer(repo, opts, dest)
  5462 
  5599 
  5463     if revs:
  5600     if revs:
  5464         revs = [repo[r].node() for r in scmutil.revrange(repo, revs)]
  5601         revs = [repo[r].node() for r in scmutil.revrange(repo, revs)]
  5465         if not revs:
  5602         if not revs:
  5466             raise error.Abort(
  5603             raise error.Abort(
  5467                 _("specified revisions evaluate to an empty set"),
  5604                 _(b"specified revisions evaluate to an empty set"),
  5468                 hint=_("use different revision arguments"),
  5605                 hint=_(b"use different revision arguments"),
  5469             )
  5606             )
  5470     elif path.pushrev:
  5607     elif path.pushrev:
  5471         # It doesn't make any sense to specify ancestor revisions. So limit
  5608         # It doesn't make any sense to specify ancestor revisions. So limit
  5472         # to DAG heads to make discovery simpler.
  5609         # to DAG heads to make discovery simpler.
  5473         expr = revsetlang.formatspec('heads(%r)', path.pushrev)
  5610         expr = revsetlang.formatspec(b'heads(%r)', path.pushrev)
  5474         revs = scmutil.revrange(repo, [expr])
  5611         revs = scmutil.revrange(repo, [expr])
  5475         revs = [repo[rev].node() for rev in revs]
  5612         revs = [repo[rev].node() for rev in revs]
  5476         if not revs:
  5613         if not revs:
  5477             raise error.Abort(
  5614             raise error.Abort(
  5478                 _('default push revset for path evaluates to an ' 'empty set')
  5615                 _(b'default push revset for path evaluates to an ' b'empty set')
  5479             )
  5616             )
  5480 
  5617 
  5481     repo._subtoppath = dest
  5618     repo._subtoppath = dest
  5482     try:
  5619     try:
  5483         # push subrepos depth-first for coherent ordering
  5620         # push subrepos depth-first for coherent ordering
  5484         c = repo['.']
  5621         c = repo[b'.']
  5485         subs = c.substate  # only repos that are committed
  5622         subs = c.substate  # only repos that are committed
  5486         for s in sorted(subs):
  5623         for s in sorted(subs):
  5487             result = c.sub(s).push(opts)
  5624             result = c.sub(s).push(opts)
  5488             if result == 0:
  5625             if result == 0:
  5489                 return not result
  5626                 return not result
  5490     finally:
  5627     finally:
  5491         del repo._subtoppath
  5628         del repo._subtoppath
  5492 
  5629 
  5493     opargs = dict(opts.get('opargs', {}))  # copy opargs since we may mutate it
  5630     opargs = dict(opts.get(b'opargs', {}))  # copy opargs since we may mutate it
  5494     opargs.setdefault('pushvars', []).extend(opts.get('pushvars', []))
  5631     opargs.setdefault(b'pushvars', []).extend(opts.get(b'pushvars', []))
  5495 
  5632 
  5496     pushop = exchange.push(
  5633     pushop = exchange.push(
  5497         repo,
  5634         repo,
  5498         other,
  5635         other,
  5499         opts.get('force'),
  5636         opts.get(b'force'),
  5500         revs=revs,
  5637         revs=revs,
  5501         newbranch=opts.get('new_branch'),
  5638         newbranch=opts.get(b'new_branch'),
  5502         bookmarks=opts.get('bookmark', ()),
  5639         bookmarks=opts.get(b'bookmark', ()),
  5503         publish=opts.get('publish'),
  5640         publish=opts.get(b'publish'),
  5504         opargs=opargs,
  5641         opargs=opargs,
  5505     )
  5642     )
  5506 
  5643 
  5507     result = not pushop.cgresult
  5644     result = not pushop.cgresult
  5508 
  5645 
  5514 
  5651 
  5515     return result
  5652     return result
  5516 
  5653 
  5517 
  5654 
  5518 @command(
  5655 @command(
  5519     'recover',
  5656     b'recover',
  5520     [('', 'verify', True, "run `hg verify` after succesful recover"),],
  5657     [(b'', b'verify', True, b"run `hg verify` after succesful recover"),],
  5521     helpcategory=command.CATEGORY_MAINTENANCE,
  5658     helpcategory=command.CATEGORY_MAINTENANCE,
  5522 )
  5659 )
  5523 def recover(ui, repo, **opts):
  5660 def recover(ui, repo, **opts):
  5524     """roll back an interrupted transaction
  5661     """roll back an interrupted transaction
  5525 
  5662 
  5535     if ret:
  5672     if ret:
  5536         if opts[r'verify']:
  5673         if opts[r'verify']:
  5537             return hg.verify(repo)
  5674             return hg.verify(repo)
  5538         else:
  5675         else:
  5539             msg = _(
  5676             msg = _(
  5540                 "(verify step skipped, run  `hg verify` to check your "
  5677                 b"(verify step skipped, run  `hg verify` to check your "
  5541                 "repository content)\n"
  5678                 b"repository content)\n"
  5542             )
  5679             )
  5543             ui.warn(msg)
  5680             ui.warn(msg)
  5544             return 0
  5681             return 0
  5545     return 1
  5682     return 1
  5546 
  5683 
  5547 
  5684 
  5548 @command(
  5685 @command(
  5549     'remove|rm',
  5686     b'remove|rm',
  5550     [
  5687     [
  5551         ('A', 'after', None, _('record delete for missing files')),
  5688         (b'A', b'after', None, _(b'record delete for missing files')),
  5552         ('f', 'force', None, _('forget added files, delete modified files')),
  5689         (b'f', b'force', None, _(b'forget added files, delete modified files')),
  5553     ]
  5690     ]
  5554     + subrepoopts
  5691     + subrepoopts
  5555     + walkopts
  5692     + walkopts
  5556     + dryrunopts,
  5693     + dryrunopts,
  5557     _('[OPTION]... FILE...'),
  5694     _(b'[OPTION]... FILE...'),
  5558     helpcategory=command.CATEGORY_WORKING_DIRECTORY,
  5695     helpcategory=command.CATEGORY_WORKING_DIRECTORY,
  5559     helpbasic=True,
  5696     helpbasic=True,
  5560     inferrepo=True,
  5697     inferrepo=True,
  5561 )
  5698 )
  5562 def remove(ui, repo, *pats, **opts):
  5699 def remove(ui, repo, *pats, **opts):
  5597 
  5734 
  5598     Returns 0 on success, 1 if any warnings encountered.
  5735     Returns 0 on success, 1 if any warnings encountered.
  5599     """
  5736     """
  5600 
  5737 
  5601     opts = pycompat.byteskwargs(opts)
  5738     opts = pycompat.byteskwargs(opts)
  5602     after, force = opts.get('after'), opts.get('force')
  5739     after, force = opts.get(b'after'), opts.get(b'force')
  5603     dryrun = opts.get('dry_run')
  5740     dryrun = opts.get(b'dry_run')
  5604     if not pats and not after:
  5741     if not pats and not after:
  5605         raise error.Abort(_('no files specified'))
  5742         raise error.Abort(_(b'no files specified'))
  5606 
  5743 
  5607     m = scmutil.match(repo[None], pats, opts)
  5744     m = scmutil.match(repo[None], pats, opts)
  5608     subrepos = opts.get('subrepos')
  5745     subrepos = opts.get(b'subrepos')
  5609     uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
  5746     uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
  5610     return cmdutil.remove(
  5747     return cmdutil.remove(
  5611         ui, repo, m, "", uipathfn, after, force, subrepos, dryrun=dryrun
  5748         ui, repo, m, b"", uipathfn, after, force, subrepos, dryrun=dryrun
  5612     )
  5749     )
  5613 
  5750 
  5614 
  5751 
  5615 @command(
  5752 @command(
  5616     'rename|move|mv',
  5753     b'rename|move|mv',
  5617     [
  5754     [
  5618         ('A', 'after', None, _('record a rename that has already occurred')),
  5755         (b'A', b'after', None, _(b'record a rename that has already occurred')),
  5619         ('f', 'force', None, _('forcibly move over an existing managed file')),
  5756         (
       
  5757             b'f',
       
  5758             b'force',
       
  5759             None,
       
  5760             _(b'forcibly move over an existing managed file'),
       
  5761         ),
  5620     ]
  5762     ]
  5621     + walkopts
  5763     + walkopts
  5622     + dryrunopts,
  5764     + dryrunopts,
  5623     _('[OPTION]... SOURCE... DEST'),
  5765     _(b'[OPTION]... SOURCE... DEST'),
  5624     helpcategory=command.CATEGORY_WORKING_DIRECTORY,
  5766     helpcategory=command.CATEGORY_WORKING_DIRECTORY,
  5625 )
  5767 )
  5626 def rename(ui, repo, *pats, **opts):
  5768 def rename(ui, repo, *pats, **opts):
  5627     """rename files; equivalent of copy + remove
  5769     """rename files; equivalent of copy + remove
  5628 
  5770 
  5643     with repo.wlock(False):
  5785     with repo.wlock(False):
  5644         return cmdutil.copy(ui, repo, pats, opts, rename=True)
  5786         return cmdutil.copy(ui, repo, pats, opts, rename=True)
  5645 
  5787 
  5646 
  5788 
  5647 @command(
  5789 @command(
  5648     'resolve',
  5790     b'resolve',
  5649     [
  5791     [
  5650         ('a', 'all', None, _('select all unresolved files')),
  5792         (b'a', b'all', None, _(b'select all unresolved files')),
  5651         ('l', 'list', None, _('list state of files needing merge')),
  5793         (b'l', b'list', None, _(b'list state of files needing merge')),
  5652         ('m', 'mark', None, _('mark files as resolved')),
  5794         (b'm', b'mark', None, _(b'mark files as resolved')),
  5653         ('u', 'unmark', None, _('mark files as unresolved')),
  5795         (b'u', b'unmark', None, _(b'mark files as unresolved')),
  5654         ('n', 'no-status', None, _('hide status prefix')),
  5796         (b'n', b'no-status', None, _(b'hide status prefix')),
  5655         ('', 're-merge', None, _('re-merge files')),
  5797         (b'', b're-merge', None, _(b're-merge files')),
  5656     ]
  5798     ]
  5657     + mergetoolopts
  5799     + mergetoolopts
  5658     + walkopts
  5800     + walkopts
  5659     + formatteropts,
  5801     + formatteropts,
  5660     _('[OPTION]... [FILE]...'),
  5802     _(b'[OPTION]... [FILE]...'),
  5661     helpcategory=command.CATEGORY_WORKING_DIRECTORY,
  5803     helpcategory=command.CATEGORY_WORKING_DIRECTORY,
  5662     inferrepo=True,
  5804     inferrepo=True,
  5663 )
  5805 )
  5664 def resolve(ui, repo, *pats, **opts):
  5806 def resolve(ui, repo, *pats, **opts):
  5665     """redo merges or set/view the merge status of files
  5807     """redo merges or set/view the merge status of files
  5712 
  5854 
  5713     Returns 0 on success, 1 if any files fail a resolve attempt.
  5855     Returns 0 on success, 1 if any files fail a resolve attempt.
  5714     """
  5856     """
  5715 
  5857 
  5716     opts = pycompat.byteskwargs(opts)
  5858     opts = pycompat.byteskwargs(opts)
  5717     confirm = ui.configbool('commands', 'resolve.confirm')
  5859     confirm = ui.configbool(b'commands', b'resolve.confirm')
  5718     flaglist = 'all mark unmark list no_status re_merge'.split()
  5860     flaglist = b'all mark unmark list no_status re_merge'.split()
  5719     all, mark, unmark, show, nostatus, remerge = [opts.get(o) for o in flaglist]
  5861     all, mark, unmark, show, nostatus, remerge = [opts.get(o) for o in flaglist]
  5720 
  5862 
  5721     actioncount = len(list(filter(None, [show, mark, unmark, remerge])))
  5863     actioncount = len(list(filter(None, [show, mark, unmark, remerge])))
  5722     if actioncount > 1:
  5864     if actioncount > 1:
  5723         raise error.Abort(_("too many actions specified"))
  5865         raise error.Abort(_(b"too many actions specified"))
  5724     elif actioncount == 0 and ui.configbool(
  5866     elif actioncount == 0 and ui.configbool(
  5725         'commands', 'resolve.explicit-re-merge'
  5867         b'commands', b'resolve.explicit-re-merge'
  5726     ):
  5868     ):
  5727         hint = _('use --mark, --unmark, --list or --re-merge')
  5869         hint = _(b'use --mark, --unmark, --list or --re-merge')
  5728         raise error.Abort(_('no action specified'), hint=hint)
  5870         raise error.Abort(_(b'no action specified'), hint=hint)
  5729     if pats and all:
  5871     if pats and all:
  5730         raise error.Abort(_("can't specify --all and patterns"))
  5872         raise error.Abort(_(b"can't specify --all and patterns"))
  5731     if not (all or pats or show or mark or unmark):
  5873     if not (all or pats or show or mark or unmark):
  5732         raise error.Abort(
  5874         raise error.Abort(
  5733             _('no files or directories specified'),
  5875             _(b'no files or directories specified'),
  5734             hint='use --all to re-merge all unresolved files',
  5876             hint=b'use --all to re-merge all unresolved files',
  5735         )
  5877         )
  5736 
  5878 
  5737     if confirm:
  5879     if confirm:
  5738         if all:
  5880         if all:
  5739             if ui.promptchoice(
  5881             if ui.promptchoice(
  5740                 _(b're-merge all unresolved files (yn)?' b'$$ &Yes $$ &No')
  5882                 _(b're-merge all unresolved files (yn)?' b'$$ &Yes $$ &No')
  5741             ):
  5883             ):
  5742                 raise error.Abort(_('user quit'))
  5884                 raise error.Abort(_(b'user quit'))
  5743         if mark and not pats:
  5885         if mark and not pats:
  5744             if ui.promptchoice(
  5886             if ui.promptchoice(
  5745                 _(
  5887                 _(
  5746                     b'mark all unresolved files as resolved (yn)?'
  5888                     b'mark all unresolved files as resolved (yn)?'
  5747                     b'$$ &Yes $$ &No'
  5889                     b'$$ &Yes $$ &No'
  5748                 )
  5890                 )
  5749             ):
  5891             ):
  5750                 raise error.Abort(_('user quit'))
  5892                 raise error.Abort(_(b'user quit'))
  5751         if unmark and not pats:
  5893         if unmark and not pats:
  5752             if ui.promptchoice(
  5894             if ui.promptchoice(
  5753                 _(
  5895                 _(
  5754                     b'mark all resolved files as unresolved (yn)?'
  5896                     b'mark all resolved files as unresolved (yn)?'
  5755                     b'$$ &Yes $$ &No'
  5897                     b'$$ &Yes $$ &No'
  5756                 )
  5898                 )
  5757             ):
  5899             ):
  5758                 raise error.Abort(_('user quit'))
  5900                 raise error.Abort(_(b'user quit'))
  5759 
  5901 
  5760     uipathfn = scmutil.getuipathfn(repo)
  5902     uipathfn = scmutil.getuipathfn(repo)
  5761 
  5903 
  5762     if show:
  5904     if show:
  5763         ui.pager('resolve')
  5905         ui.pager(b'resolve')
  5764         fm = ui.formatter('resolve', opts)
  5906         fm = ui.formatter(b'resolve', opts)
  5765         ms = mergemod.mergestate.read(repo)
  5907         ms = mergemod.mergestate.read(repo)
  5766         wctx = repo[None]
  5908         wctx = repo[None]
  5767         m = scmutil.match(wctx, pats, opts)
  5909         m = scmutil.match(wctx, pats, opts)
  5768 
  5910 
  5769         # Labels and keys based on merge state.  Unresolved path conflicts show
  5911         # Labels and keys based on merge state.  Unresolved path conflicts show
  5770         # as 'P'.  Resolved path conflicts show as 'R', the same as normal
  5912         # as 'P'.  Resolved path conflicts show as 'R', the same as normal
  5771         # resolved conflicts.
  5913         # resolved conflicts.
  5772         mergestateinfo = {
  5914         mergestateinfo = {
  5773             mergemod.MERGE_RECORD_UNRESOLVED: ('resolve.unresolved', 'U'),
  5915             mergemod.MERGE_RECORD_UNRESOLVED: (b'resolve.unresolved', b'U'),
  5774             mergemod.MERGE_RECORD_RESOLVED: ('resolve.resolved', 'R'),
  5916             mergemod.MERGE_RECORD_RESOLVED: (b'resolve.resolved', b'R'),
  5775             mergemod.MERGE_RECORD_UNRESOLVED_PATH: ('resolve.unresolved', 'P'),
  5917             mergemod.MERGE_RECORD_UNRESOLVED_PATH: (
  5776             mergemod.MERGE_RECORD_RESOLVED_PATH: ('resolve.resolved', 'R'),
  5918                 b'resolve.unresolved',
       
  5919                 b'P',
       
  5920             ),
       
  5921             mergemod.MERGE_RECORD_RESOLVED_PATH: (b'resolve.resolved', b'R'),
  5777             mergemod.MERGE_RECORD_DRIVER_RESOLVED: (
  5922             mergemod.MERGE_RECORD_DRIVER_RESOLVED: (
  5778                 'resolve.driverresolved',
  5923                 b'resolve.driverresolved',
  5779                 'D',
  5924                 b'D',
  5780             ),
  5925             ),
  5781         }
  5926         }
  5782 
  5927 
  5783         for f in ms:
  5928         for f in ms:
  5784             if not m(f):
  5929             if not m(f):
  5785                 continue
  5930                 continue
  5786 
  5931 
  5787             label, key = mergestateinfo[ms[f]]
  5932             label, key = mergestateinfo[ms[f]]
  5788             fm.startitem()
  5933             fm.startitem()
  5789             fm.context(ctx=wctx)
  5934             fm.context(ctx=wctx)
  5790             fm.condwrite(not nostatus, 'mergestatus', '%s ', key, label=label)
  5935             fm.condwrite(not nostatus, b'mergestatus', b'%s ', key, label=label)
  5791             fm.data(path=f)
  5936             fm.data(path=f)
  5792             fm.plain('%s\n' % uipathfn(f), label=label)
  5937             fm.plain(b'%s\n' % uipathfn(f), label=label)
  5793         fm.end()
  5938         fm.end()
  5794         return 0
  5939         return 0
  5795 
  5940 
  5796     with repo.wlock():
  5941     with repo.wlock():
  5797         ms = mergemod.mergestate.read(repo)
  5942         ms = mergemod.mergestate.read(repo)
  5798 
  5943 
  5799         if not (ms.active() or repo.dirstate.p2() != nullid):
  5944         if not (ms.active() or repo.dirstate.p2() != nullid):
  5800             raise error.Abort(
  5945             raise error.Abort(
  5801                 _('resolve command not applicable when not merging')
  5946                 _(b'resolve command not applicable when not merging')
  5802             )
  5947             )
  5803 
  5948 
  5804         wctx = repo[None]
  5949         wctx = repo[None]
  5805 
  5950 
  5806         if (
  5951         if (
  5819         runconclude = False
  5964         runconclude = False
  5820 
  5965 
  5821         tocomplete = []
  5966         tocomplete = []
  5822         hasconflictmarkers = []
  5967         hasconflictmarkers = []
  5823         if mark:
  5968         if mark:
  5824             markcheck = ui.config('commands', 'resolve.mark-check')
  5969             markcheck = ui.config(b'commands', b'resolve.mark-check')
  5825             if markcheck not in ['warn', 'abort']:
  5970             if markcheck not in [b'warn', b'abort']:
  5826                 # Treat all invalid / unrecognized values as 'none'.
  5971                 # Treat all invalid / unrecognized values as 'none'.
  5827                 markcheck = False
  5972                 markcheck = False
  5828         for f in ms:
  5973         for f in ms:
  5829             if not m(f):
  5974             if not m(f):
  5830                 continue
  5975                 continue
  5836             if ms[f] == mergemod.MERGE_RECORD_DRIVER_RESOLVED:
  5981             if ms[f] == mergemod.MERGE_RECORD_DRIVER_RESOLVED:
  5837                 exact = m.exact(f)
  5982                 exact = m.exact(f)
  5838                 if mark:
  5983                 if mark:
  5839                     if exact:
  5984                     if exact:
  5840                         ui.warn(
  5985                         ui.warn(
  5841                             _('not marking %s as it is driver-resolved\n')
  5986                             _(b'not marking %s as it is driver-resolved\n')
  5842                             % uipathfn(f)
  5987                             % uipathfn(f)
  5843                         )
  5988                         )
  5844                 elif unmark:
  5989                 elif unmark:
  5845                     if exact:
  5990                     if exact:
  5846                         ui.warn(
  5991                         ui.warn(
  5847                             _('not unmarking %s as it is driver-resolved\n')
  5992                             _(b'not unmarking %s as it is driver-resolved\n')
  5848                             % uipathfn(f)
  5993                             % uipathfn(f)
  5849                         )
  5994                         )
  5850                 else:
  5995                 else:
  5851                     runconclude = True
  5996                     runconclude = True
  5852                 continue
  5997                 continue
  5860                     ms.mark(f, mergemod.MERGE_RECORD_RESOLVED_PATH)
  6005                     ms.mark(f, mergemod.MERGE_RECORD_RESOLVED_PATH)
  5861                 elif unmark:
  6006                 elif unmark:
  5862                     ms.mark(f, mergemod.MERGE_RECORD_UNRESOLVED_PATH)
  6007                     ms.mark(f, mergemod.MERGE_RECORD_UNRESOLVED_PATH)
  5863                 elif ms[f] == mergemod.MERGE_RECORD_UNRESOLVED_PATH:
  6008                 elif ms[f] == mergemod.MERGE_RECORD_UNRESOLVED_PATH:
  5864                     ui.warn(
  6009                     ui.warn(
  5865                         _('%s: path conflict must be resolved manually\n')
  6010                         _(b'%s: path conflict must be resolved manually\n')
  5866                         % uipathfn(f)
  6011                         % uipathfn(f)
  5867                     )
  6012                     )
  5868                 continue
  6013                 continue
  5869 
  6014 
  5870             if mark:
  6015             if mark:
  5880                 ms.mark(f, mergemod.MERGE_RECORD_UNRESOLVED)
  6025                 ms.mark(f, mergemod.MERGE_RECORD_UNRESOLVED)
  5881             else:
  6026             else:
  5882                 # backup pre-resolve (merge uses .orig for its own purposes)
  6027                 # backup pre-resolve (merge uses .orig for its own purposes)
  5883                 a = repo.wjoin(f)
  6028                 a = repo.wjoin(f)
  5884                 try:
  6029                 try:
  5885                     util.copyfile(a, a + ".resolve")
  6030                     util.copyfile(a, a + b".resolve")
  5886                 except (IOError, OSError) as inst:
  6031                 except (IOError, OSError) as inst:
  5887                     if inst.errno != errno.ENOENT:
  6032                     if inst.errno != errno.ENOENT:
  5888                         raise
  6033                         raise
  5889 
  6034 
  5890                 try:
  6035                 try:
  5891                     # preresolve file
  6036                     # preresolve file
  5892                     overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
  6037                     overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
  5893                     with ui.configoverride(overrides, 'resolve'):
  6038                     with ui.configoverride(overrides, b'resolve'):
  5894                         complete, r = ms.preresolve(f, wctx)
  6039                         complete, r = ms.preresolve(f, wctx)
  5895                     if not complete:
  6040                     if not complete:
  5896                         tocomplete.append(f)
  6041                         tocomplete.append(f)
  5897                     elif r:
  6042                     elif r:
  5898                         ret = 1
  6043                         ret = 1
  5902                 # replace filemerge's .orig file with our resolve file, but only
  6047                 # replace filemerge's .orig file with our resolve file, but only
  5903                 # for merges that are complete
  6048                 # for merges that are complete
  5904                 if complete:
  6049                 if complete:
  5905                     try:
  6050                     try:
  5906                         util.rename(
  6051                         util.rename(
  5907                             a + ".resolve", scmutil.backuppath(ui, repo, f)
  6052                             a + b".resolve", scmutil.backuppath(ui, repo, f)
  5908                         )
  6053                         )
  5909                     except OSError as inst:
  6054                     except OSError as inst:
  5910                         if inst.errno != errno.ENOENT:
  6055                         if inst.errno != errno.ENOENT:
  5911                             raise
  6056                             raise
  5912 
  6057 
  5913         if hasconflictmarkers:
  6058         if hasconflictmarkers:
  5914             ui.warn(
  6059             ui.warn(
  5915                 _(
  6060                 _(
  5916                     'warning: the following files still have conflict '
  6061                     b'warning: the following files still have conflict '
  5917                     'markers:\n'
  6062                     b'markers:\n'
  5918                 )
  6063                 )
  5919                 + ''.join('  ' + uipathfn(f) + '\n' for f in hasconflictmarkers)
  6064                 + b''.join(
       
  6065                     b'  ' + uipathfn(f) + b'\n' for f in hasconflictmarkers
       
  6066                 )
  5920             )
  6067             )
  5921             if markcheck == 'abort' and not all and not pats:
  6068             if markcheck == b'abort' and not all and not pats:
  5922                 raise error.Abort(
  6069                 raise error.Abort(
  5923                     _('conflict markers detected'),
  6070                     _(b'conflict markers detected'),
  5924                     hint=_('use --all to mark anyway'),
  6071                     hint=_(b'use --all to mark anyway'),
  5925                 )
  6072                 )
  5926 
  6073 
  5927         for f in tocomplete:
  6074         for f in tocomplete:
  5928             try:
  6075             try:
  5929                 # resolve file
  6076                 # resolve file
  5930                 overrides = {('ui', 'forcemerge'): opts.get('tool', '')}
  6077                 overrides = {(b'ui', b'forcemerge'): opts.get(b'tool', b'')}
  5931                 with ui.configoverride(overrides, 'resolve'):
  6078                 with ui.configoverride(overrides, b'resolve'):
  5932                     r = ms.resolve(f, wctx)
  6079                     r = ms.resolve(f, wctx)
  5933                 if r:
  6080                 if r:
  5934                     ret = 1
  6081                     ret = 1
  5935             finally:
  6082             finally:
  5936                 ms.commit()
  6083                 ms.commit()
  5937 
  6084 
  5938             # replace filemerge's .orig file with our resolve file
  6085             # replace filemerge's .orig file with our resolve file
  5939             a = repo.wjoin(f)
  6086             a = repo.wjoin(f)
  5940             try:
  6087             try:
  5941                 util.rename(a + ".resolve", scmutil.backuppath(ui, repo, f))
  6088                 util.rename(a + b".resolve", scmutil.backuppath(ui, repo, f))
  5942             except OSError as inst:
  6089             except OSError as inst:
  5943                 if inst.errno != errno.ENOENT:
  6090                 if inst.errno != errno.ENOENT:
  5944                     raise
  6091                     raise
  5945 
  6092 
  5946         ms.commit()
  6093         ms.commit()
  5947         ms.recordactions()
  6094         ms.recordactions()
  5948 
  6095 
  5949         if not didwork and pats:
  6096         if not didwork and pats:
  5950             hint = None
  6097             hint = None
  5951             if not any([p for p in pats if p.find(':') >= 0]):
  6098             if not any([p for p in pats if p.find(b':') >= 0]):
  5952                 pats = ['path:%s' % p for p in pats]
  6099                 pats = [b'path:%s' % p for p in pats]
  5953                 m = scmutil.match(wctx, pats, opts)
  6100                 m = scmutil.match(wctx, pats, opts)
  5954                 for f in ms:
  6101                 for f in ms:
  5955                     if not m(f):
  6102                     if not m(f):
  5956                         continue
  6103                         continue
  5957 
  6104 
  5958                     def flag(o):
  6105                     def flag(o):
  5959                         if o == 're_merge':
  6106                         if o == b're_merge':
  5960                             return '--re-merge '
  6107                             return b'--re-merge '
  5961                         return '-%s ' % o[0:1]
  6108                         return b'-%s ' % o[0:1]
  5962 
  6109 
  5963                     flags = ''.join([flag(o) for o in flaglist if opts.get(o)])
  6110                     flags = b''.join([flag(o) for o in flaglist if opts.get(o)])
  5964                     hint = _("(try: hg resolve %s%s)\n") % (
  6111                     hint = _(b"(try: hg resolve %s%s)\n") % (
  5965                         flags,
  6112                         flags,
  5966                         ' '.join(pats),
  6113                         b' '.join(pats),
  5967                     )
  6114                     )
  5968                     break
  6115                     break
  5969             ui.warn(_("arguments do not match paths that need resolving\n"))
  6116             ui.warn(_(b"arguments do not match paths that need resolving\n"))
  5970             if hint:
  6117             if hint:
  5971                 ui.warn(hint)
  6118                 ui.warn(hint)
  5972         elif ms.mergedriver and ms.mdstate() != 's':
  6119         elif ms.mergedriver and ms.mdstate() != b's':
  5973             # run conclude step when either a driver-resolved file is requested
  6120             # run conclude step when either a driver-resolved file is requested
  5974             # or there are no driver-resolved files
  6121             # or there are no driver-resolved files
  5975             # we can't use 'ret' to determine whether any files are unresolved
  6122             # we can't use 'ret' to determine whether any files are unresolved
  5976             # because we might not have tried to resolve some
  6123             # because we might not have tried to resolve some
  5977             if (runconclude or not list(ms.driverresolved())) and not list(
  6124             if (runconclude or not list(ms.driverresolved())) and not list(
  5984 
  6131 
  5985     # Nudge users into finishing an unfinished operation
  6132     # Nudge users into finishing an unfinished operation
  5986     unresolvedf = list(ms.unresolved())
  6133     unresolvedf = list(ms.unresolved())
  5987     driverresolvedf = list(ms.driverresolved())
  6134     driverresolvedf = list(ms.driverresolved())
  5988     if not unresolvedf and not driverresolvedf:
  6135     if not unresolvedf and not driverresolvedf:
  5989         ui.status(_('(no more unresolved files)\n'))
  6136         ui.status(_(b'(no more unresolved files)\n'))
  5990         cmdutil.checkafterresolved(repo)
  6137         cmdutil.checkafterresolved(repo)
  5991     elif not unresolvedf:
  6138     elif not unresolvedf:
  5992         ui.status(
  6139         ui.status(
  5993             _(
  6140             _(
  5994                 '(no more unresolved files -- '
  6141                 b'(no more unresolved files -- '
  5995                 'run "hg resolve --all" to conclude)\n'
  6142                 b'run "hg resolve --all" to conclude)\n'
  5996             )
  6143             )
  5997         )
  6144         )
  5998 
  6145 
  5999     return ret
  6146     return ret
  6000 
  6147 
  6001 
  6148 
  6002 @command(
  6149 @command(
  6003     'revert',
  6150     b'revert',
  6004     [
  6151     [
  6005         ('a', 'all', None, _('revert all changes when no arguments given')),
  6152         (b'a', b'all', None, _(b'revert all changes when no arguments given')),
  6006         ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
  6153         (b'd', b'date', b'', _(b'tipmost revision matching date'), _(b'DATE')),
  6007         ('r', 'rev', '', _('revert to the specified revision'), _('REV')),
  6154         (b'r', b'rev', b'', _(b'revert to the specified revision'), _(b'REV')),
  6008         ('C', 'no-backup', None, _('do not save backup copies of files')),
  6155         (b'C', b'no-backup', None, _(b'do not save backup copies of files')),
  6009         ('i', 'interactive', None, _('interactively select the changes')),
  6156         (b'i', b'interactive', None, _(b'interactively select the changes')),
  6010     ]
  6157     ]
  6011     + walkopts
  6158     + walkopts
  6012     + dryrunopts,
  6159     + dryrunopts,
  6013     _('[OPTION]... [-r REV] [NAME]...'),
  6160     _(b'[OPTION]... [-r REV] [NAME]...'),
  6014     helpcategory=command.CATEGORY_WORKING_DIRECTORY,
  6161     helpcategory=command.CATEGORY_WORKING_DIRECTORY,
  6015 )
  6162 )
  6016 def revert(ui, repo, *pats, **opts):
  6163 def revert(ui, repo, *pats, **opts):
  6017     """restore files to their checkout state
  6164     """restore files to their checkout state
  6018 
  6165 
  6049 
  6196 
  6050     Returns 0 on success.
  6197     Returns 0 on success.
  6051     """
  6198     """
  6052 
  6199 
  6053     opts = pycompat.byteskwargs(opts)
  6200     opts = pycompat.byteskwargs(opts)
  6054     if opts.get("date"):
  6201     if opts.get(b"date"):
  6055         if opts.get("rev"):
  6202         if opts.get(b"rev"):
  6056             raise error.Abort(_("you can't specify a revision and a date"))
  6203             raise error.Abort(_(b"you can't specify a revision and a date"))
  6057         opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
  6204         opts[b"rev"] = cmdutil.finddate(ui, repo, opts[b"date"])
  6058 
  6205 
  6059     parent, p2 = repo.dirstate.parents()
  6206     parent, p2 = repo.dirstate.parents()
  6060     if not opts.get('rev') and p2 != nullid:
  6207     if not opts.get(b'rev') and p2 != nullid:
  6061         # revert after merge is a trap for new users (issue2915)
  6208         # revert after merge is a trap for new users (issue2915)
  6062         raise error.Abort(
  6209         raise error.Abort(
  6063             _('uncommitted merge with no revision specified'),
  6210             _(b'uncommitted merge with no revision specified'),
  6064             hint=_("use 'hg update' or see 'hg help revert'"),
  6211             hint=_(b"use 'hg update' or see 'hg help revert'"),
  6065         )
  6212         )
  6066 
  6213 
  6067     rev = opts.get('rev')
  6214     rev = opts.get(b'rev')
  6068     if rev:
  6215     if rev:
  6069         repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
  6216         repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
  6070     ctx = scmutil.revsingle(repo, rev)
  6217     ctx = scmutil.revsingle(repo, rev)
  6071 
  6218 
  6072     if not (
  6219     if not (
  6073         pats
  6220         pats
  6074         or opts.get('include')
  6221         or opts.get(b'include')
  6075         or opts.get('exclude')
  6222         or opts.get(b'exclude')
  6076         or opts.get('all')
  6223         or opts.get(b'all')
  6077         or opts.get('interactive')
  6224         or opts.get(b'interactive')
  6078     ):
  6225     ):
  6079         msg = _("no files or directories specified")
  6226         msg = _(b"no files or directories specified")
  6080         if p2 != nullid:
  6227         if p2 != nullid:
  6081             hint = _(
  6228             hint = _(
  6082                 "uncommitted merge, use --all to discard all changes,"
  6229                 b"uncommitted merge, use --all to discard all changes,"
  6083                 " or 'hg update -C .' to abort the merge"
  6230                 b" or 'hg update -C .' to abort the merge"
  6084             )
  6231             )
  6085             raise error.Abort(msg, hint=hint)
  6232             raise error.Abort(msg, hint=hint)
  6086         dirty = any(repo.status())
  6233         dirty = any(repo.status())
  6087         node = ctx.node()
  6234         node = ctx.node()
  6088         if node != parent:
  6235         if node != parent:
  6089             if dirty:
  6236             if dirty:
  6090                 hint = (
  6237                 hint = (
  6091                     _(
  6238                     _(
  6092                         "uncommitted changes, use --all to discard all"
  6239                         b"uncommitted changes, use --all to discard all"
  6093                         " changes, or 'hg update %d' to update"
  6240                         b" changes, or 'hg update %d' to update"
  6094                     )
  6241                     )
  6095                     % ctx.rev()
  6242                     % ctx.rev()
  6096                 )
  6243                 )
  6097             else:
  6244             else:
  6098                 hint = (
  6245                 hint = (
  6099                     _(
  6246                     _(
  6100                         "use --all to revert all files,"
  6247                         b"use --all to revert all files,"
  6101                         " or 'hg update %d' to update"
  6248                         b" or 'hg update %d' to update"
  6102                     )
  6249                     )
  6103                     % ctx.rev()
  6250                     % ctx.rev()
  6104                 )
  6251                 )
  6105         elif dirty:
  6252         elif dirty:
  6106             hint = _("uncommitted changes, use --all to discard all changes")
  6253             hint = _(b"uncommitted changes, use --all to discard all changes")
  6107         else:
  6254         else:
  6108             hint = _("use --all to revert all files")
  6255             hint = _(b"use --all to revert all files")
  6109         raise error.Abort(msg, hint=hint)
  6256         raise error.Abort(msg, hint=hint)
  6110 
  6257 
  6111     return cmdutil.revert(
  6258     return cmdutil.revert(
  6112         ui, repo, ctx, (parent, p2), *pats, **pycompat.strkwargs(opts)
  6259         ui, repo, ctx, (parent, p2), *pats, **pycompat.strkwargs(opts)
  6113     )
  6260     )
  6114 
  6261 
  6115 
  6262 
  6116 @command(
  6263 @command(
  6117     'rollback',
  6264     b'rollback',
  6118     dryrunopts + [('f', 'force', False, _('ignore safety measures'))],
  6265     dryrunopts + [(b'f', b'force', False, _(b'ignore safety measures'))],
  6119     helpcategory=command.CATEGORY_MAINTENANCE,
  6266     helpcategory=command.CATEGORY_MAINTENANCE,
  6120 )
  6267 )
  6121 def rollback(ui, repo, **opts):
  6268 def rollback(ui, repo, **opts):
  6122     """roll back the last transaction (DANGEROUS) (DEPRECATED)
  6269     """roll back the last transaction (DANGEROUS) (DEPRECATED)
  6123 
  6270 
  6161     repository; for example an in-progress pull from the repository
  6308     repository; for example an in-progress pull from the repository
  6162     may fail if a rollback is performed.
  6309     may fail if a rollback is performed.
  6163 
  6310 
  6164     Returns 0 on success, 1 if no rollback data is available.
  6311     Returns 0 on success, 1 if no rollback data is available.
  6165     """
  6312     """
  6166     if not ui.configbool('ui', 'rollback'):
  6313     if not ui.configbool(b'ui', b'rollback'):
  6167         raise error.Abort(
  6314         raise error.Abort(
  6168             _('rollback is disabled because it is unsafe'),
  6315             _(b'rollback is disabled because it is unsafe'),
  6169             hint='see `hg help -v rollback` for information',
  6316             hint=b'see `hg help -v rollback` for information',
  6170         )
  6317         )
  6171     return repo.rollback(dryrun=opts.get(r'dry_run'), force=opts.get(r'force'))
  6318     return repo.rollback(dryrun=opts.get(r'dry_run'), force=opts.get(r'force'))
  6172 
  6319 
  6173 
  6320 
  6174 @command(
  6321 @command(
  6175     'root',
  6322     b'root',
  6176     [] + formatteropts,
  6323     [] + formatteropts,
  6177     intents={INTENT_READONLY},
  6324     intents={INTENT_READONLY},
  6178     helpcategory=command.CATEGORY_WORKING_DIRECTORY,
  6325     helpcategory=command.CATEGORY_WORKING_DIRECTORY,
  6179 )
  6326 )
  6180 def root(ui, repo, **opts):
  6327 def root(ui, repo, **opts):
  6193       :storepath: String. Path to the directory holding versioned data.
  6340       :storepath: String. Path to the directory holding versioned data.
  6194 
  6341 
  6195     Returns 0 on success.
  6342     Returns 0 on success.
  6196     """
  6343     """
  6197     opts = pycompat.byteskwargs(opts)
  6344     opts = pycompat.byteskwargs(opts)
  6198     with ui.formatter('root', opts) as fm:
  6345     with ui.formatter(b'root', opts) as fm:
  6199         fm.startitem()
  6346         fm.startitem()
  6200         fm.write('reporoot', '%s\n', repo.root)
  6347         fm.write(b'reporoot', b'%s\n', repo.root)
  6201         fm.data(hgpath=repo.path, storepath=repo.spath)
  6348         fm.data(hgpath=repo.path, storepath=repo.spath)
  6202 
  6349 
  6203 
  6350 
  6204 @command(
  6351 @command(
  6205     'serve',
  6352     b'serve',
  6206     [
  6353     [
  6207         (
  6354         (
  6208             'A',
  6355             b'A',
  6209             'accesslog',
  6356             b'accesslog',
  6210             '',
  6357             b'',
  6211             _('name of access log file to write to'),
  6358             _(b'name of access log file to write to'),
  6212             _('FILE'),
  6359             _(b'FILE'),
  6213         ),
  6360         ),
  6214         ('d', 'daemon', None, _('run server in background')),
  6361         (b'd', b'daemon', None, _(b'run server in background')),
  6215         ('', 'daemon-postexec', [], _('used internally by daemon mode')),
  6362         (b'', b'daemon-postexec', [], _(b'used internally by daemon mode')),
  6216         (
  6363         (
  6217             'E',
  6364             b'E',
  6218             'errorlog',
  6365             b'errorlog',
  6219             '',
  6366             b'',
  6220             _('name of error log file to write to'),
  6367             _(b'name of error log file to write to'),
  6221             _('FILE'),
  6368             _(b'FILE'),
  6222         ),
  6369         ),
  6223         # use string type, then we can check if something was passed
  6370         # use string type, then we can check if something was passed
  6224         ('p', 'port', '', _('port to listen on (default: 8000)'), _('PORT')),
  6371         (
  6225         (
  6372             b'p',
  6226             'a',
  6373             b'port',
  6227             'address',
  6374             b'',
  6228             '',
  6375             _(b'port to listen on (default: 8000)'),
  6229             _('address to listen on (default: all interfaces)'),
  6376             _(b'PORT'),
  6230             _('ADDR'),
  6377         ),
  6231         ),
  6378         (
  6232         (
  6379             b'a',
  6233             '',
  6380             b'address',
  6234             'prefix',
  6381             b'',
  6235             '',
  6382             _(b'address to listen on (default: all interfaces)'),
  6236             _('prefix path to serve from (default: server root)'),
  6383             _(b'ADDR'),
  6237             _('PREFIX'),
  6384         ),
  6238         ),
  6385         (
  6239         (
  6386             b'',
  6240             'n',
  6387             b'prefix',
  6241             'name',
  6388             b'',
  6242             '',
  6389             _(b'prefix path to serve from (default: server root)'),
  6243             _('name to show in web pages (default: working directory)'),
  6390             _(b'PREFIX'),
  6244             _('NAME'),
  6391         ),
  6245         ),
  6392         (
  6246         (
  6393             b'n',
  6247             '',
  6394             b'name',
  6248             'web-conf',
  6395             b'',
  6249             '',
  6396             _(b'name to show in web pages (default: working directory)'),
  6250             _("name of the hgweb config file (see 'hg help hgweb')"),
  6397             _(b'NAME'),
  6251             _('FILE'),
  6398         ),
  6252         ),
  6399         (
  6253         (
  6400             b'',
  6254             '',
  6401             b'web-conf',
  6255             'webdir-conf',
  6402             b'',
  6256             '',
  6403             _(b"name of the hgweb config file (see 'hg help hgweb')"),
  6257             _('name of the hgweb config file (DEPRECATED)'),
  6404             _(b'FILE'),
  6258             _('FILE'),
  6405         ),
  6259         ),
  6406         (
  6260         (
  6407             b'',
  6261             '',
  6408             b'webdir-conf',
  6262             'pid-file',
  6409             b'',
  6263             '',
  6410             _(b'name of the hgweb config file (DEPRECATED)'),
  6264             _('name of file to write process ID to'),
  6411             _(b'FILE'),
  6265             _('FILE'),
  6412         ),
  6266         ),
  6413         (
  6267         ('', 'stdio', None, _('for remote clients (ADVANCED)')),
  6414             b'',
  6268         ('', 'cmdserver', '', _('for remote clients (ADVANCED)'), _('MODE')),
  6415             b'pid-file',
  6269         ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')),
  6416             b'',
  6270         ('', 'style', '', _('template style to use'), _('STYLE')),
  6417             _(b'name of file to write process ID to'),
  6271         ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
  6418             _(b'FILE'),
  6272         ('', 'certificate', '', _('SSL certificate file'), _('FILE')),
  6419         ),
  6273         ('', 'print-url', None, _('start and print only the URL')),
  6420         (b'', b'stdio', None, _(b'for remote clients (ADVANCED)')),
       
  6421         (
       
  6422             b'',
       
  6423             b'cmdserver',
       
  6424             b'',
       
  6425             _(b'for remote clients (ADVANCED)'),
       
  6426             _(b'MODE'),
       
  6427         ),
       
  6428         (b't', b'templates', b'', _(b'web templates to use'), _(b'TEMPLATE')),
       
  6429         (b'', b'style', b'', _(b'template style to use'), _(b'STYLE')),
       
  6430         (b'6', b'ipv6', None, _(b'use IPv6 in addition to IPv4')),
       
  6431         (b'', b'certificate', b'', _(b'SSL certificate file'), _(b'FILE')),
       
  6432         (b'', b'print-url', None, _(b'start and print only the URL')),
  6274     ]
  6433     ]
  6275     + subrepoopts,
  6434     + subrepoopts,
  6276     _('[OPTION]...'),
  6435     _(b'[OPTION]...'),
  6277     helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
  6436     helpcategory=command.CATEGORY_REMOTE_REPO_MANAGEMENT,
  6278     helpbasic=True,
  6437     helpbasic=True,
  6279     optionalrepo=True,
  6438     optionalrepo=True,
  6280 )
  6439 )
  6281 def serve(ui, repo, **opts):
  6440 def serve(ui, repo, **opts):
  6302 
  6461 
  6303     Returns 0 on success.
  6462     Returns 0 on success.
  6304     """
  6463     """
  6305 
  6464 
  6306     opts = pycompat.byteskwargs(opts)
  6465     opts = pycompat.byteskwargs(opts)
  6307     if opts["stdio"] and opts["cmdserver"]:
  6466     if opts[b"stdio"] and opts[b"cmdserver"]:
  6308         raise error.Abort(_("cannot use --stdio with --cmdserver"))
  6467         raise error.Abort(_(b"cannot use --stdio with --cmdserver"))
  6309     if opts["print_url"] and ui.verbose:
  6468     if opts[b"print_url"] and ui.verbose:
  6310         raise error.Abort(_("cannot use --print-url with --verbose"))
  6469         raise error.Abort(_(b"cannot use --print-url with --verbose"))
  6311 
  6470 
  6312     if opts["stdio"]:
  6471     if opts[b"stdio"]:
  6313         if repo is None:
  6472         if repo is None:
  6314             raise error.RepoError(
  6473             raise error.RepoError(
  6315                 _("there is no Mercurial repository here" " (.hg not found)")
  6474                 _(b"there is no Mercurial repository here" b" (.hg not found)")
  6316             )
  6475             )
  6317         s = wireprotoserver.sshserver(ui, repo)
  6476         s = wireprotoserver.sshserver(ui, repo)
  6318         s.serve_forever()
  6477         s.serve_forever()
  6319 
  6478 
  6320     service = server.createservice(ui, repo, opts)
  6479     service = server.createservice(ui, repo, opts)
  6321     return server.runservice(opts, initfn=service.init, runfn=service.run)
  6480     return server.runservice(opts, initfn=service.init, runfn=service.run)
  6322 
  6481 
  6323 
  6482 
  6324 @command(
  6483 @command(
  6325     'shelve',
  6484     b'shelve',
  6326     [
  6485     [
  6327         (
  6486         (
  6328             'A',
  6487             b'A',
  6329             'addremove',
  6488             b'addremove',
  6330             None,
  6489             None,
  6331             _('mark new/missing files as added/removed before shelving'),
  6490             _(b'mark new/missing files as added/removed before shelving'),
  6332         ),
  6491         ),
  6333         ('u', 'unknown', None, _('store unknown files in the shelve')),
  6492         (b'u', b'unknown', None, _(b'store unknown files in the shelve')),
  6334         ('', 'cleanup', None, _('delete all shelved changes')),
  6493         (b'', b'cleanup', None, _(b'delete all shelved changes')),
  6335         ('', 'date', '', _('shelve with the specified commit date'), _('DATE')),
  6494         (
  6336         ('d', 'delete', None, _('delete the named shelved change(s)')),
  6495             b'',
  6337         ('e', 'edit', False, _('invoke editor on commit messages')),
  6496             b'date',
  6338         (
  6497             b'',
  6339             'k',
  6498             _(b'shelve with the specified commit date'),
  6340             'keep',
  6499             _(b'DATE'),
       
  6500         ),
       
  6501         (b'd', b'delete', None, _(b'delete the named shelved change(s)')),
       
  6502         (b'e', b'edit', False, _(b'invoke editor on commit messages')),
       
  6503         (
       
  6504             b'k',
       
  6505             b'keep',
  6341             False,
  6506             False,
  6342             _('shelve, but keep changes in the working directory'),
  6507             _(b'shelve, but keep changes in the working directory'),
  6343         ),
  6508         ),
  6344         ('l', 'list', None, _('list current shelves')),
  6509         (b'l', b'list', None, _(b'list current shelves')),
  6345         ('m', 'message', '', _('use text as shelve message'), _('TEXT')),
  6510         (b'm', b'message', b'', _(b'use text as shelve message'), _(b'TEXT')),
  6346         (
  6511         (
  6347             'n',
  6512             b'n',
  6348             'name',
  6513             b'name',
  6349             '',
  6514             b'',
  6350             _('use the given name for the shelved commit'),
  6515             _(b'use the given name for the shelved commit'),
  6351             _('NAME'),
  6516             _(b'NAME'),
  6352         ),
  6517         ),
  6353         (
  6518         (
  6354             'p',
  6519             b'p',
  6355             'patch',
  6520             b'patch',
  6356             None,
  6521             None,
  6357             _(
  6522             _(
  6358                 'output patches for changes (provide the names of the shelved '
  6523                 b'output patches for changes (provide the names of the shelved '
  6359                 'changes as positional arguments)'
  6524                 b'changes as positional arguments)'
  6360             ),
  6525             ),
  6361         ),
  6526         ),
  6362         ('i', 'interactive', None, _('interactive mode')),
  6527         (b'i', b'interactive', None, _(b'interactive mode')),
  6363         (
  6528         (
  6364             '',
  6529             b'',
  6365             'stat',
  6530             b'stat',
  6366             None,
  6531             None,
  6367             _(
  6532             _(
  6368                 'output diffstat-style summary of changes (provide the names of '
  6533                 b'output diffstat-style summary of changes (provide the names of '
  6369                 'the shelved changes as positional arguments)'
  6534                 b'the shelved changes as positional arguments)'
  6370             ),
  6535             ),
  6371         ),
  6536         ),
  6372     ]
  6537     ]
  6373     + cmdutil.walkopts,
  6538     + cmdutil.walkopts,
  6374     _('hg shelve [OPTION]... [FILE]...'),
  6539     _(b'hg shelve [OPTION]... [FILE]...'),
  6375     helpcategory=command.CATEGORY_WORKING_DIRECTORY,
  6540     helpcategory=command.CATEGORY_WORKING_DIRECTORY,
  6376 )
  6541 )
  6377 def shelve(ui, repo, *pats, **opts):
  6542 def shelve(ui, repo, *pats, **opts):
  6378     '''save and set aside changes from the working directory
  6543     '''save and set aside changes from the working directory
  6379 
  6544 
  6407     To delete specific shelved changes, use ``--delete``. To delete
  6572     To delete specific shelved changes, use ``--delete``. To delete
  6408     all shelved changes, use ``--cleanup``.
  6573     all shelved changes, use ``--cleanup``.
  6409     '''
  6574     '''
  6410     opts = pycompat.byteskwargs(opts)
  6575     opts = pycompat.byteskwargs(opts)
  6411     allowables = [
  6576     allowables = [
  6412         ('addremove', {'create'}),  # 'create' is pseudo action
  6577         (b'addremove', {b'create'}),  # 'create' is pseudo action
  6413         ('unknown', {'create'}),
  6578         (b'unknown', {b'create'}),
  6414         ('cleanup', {'cleanup'}),
  6579         (b'cleanup', {b'cleanup'}),
  6415         #       ('date', {'create'}), # ignored for passing '--date "0 0"' in tests
  6580         #       ('date', {'create'}), # ignored for passing '--date "0 0"' in tests
  6416         ('delete', {'delete'}),
  6581         (b'delete', {b'delete'}),
  6417         ('edit', {'create'}),
  6582         (b'edit', {b'create'}),
  6418         ('keep', {'create'}),
  6583         (b'keep', {b'create'}),
  6419         ('list', {'list'}),
  6584         (b'list', {b'list'}),
  6420         ('message', {'create'}),
  6585         (b'message', {b'create'}),
  6421         ('name', {'create'}),
  6586         (b'name', {b'create'}),
  6422         ('patch', {'patch', 'list'}),
  6587         (b'patch', {b'patch', b'list'}),
  6423         ('stat', {'stat', 'list'}),
  6588         (b'stat', {b'stat', b'list'}),
  6424     ]
  6589     ]
  6425 
  6590 
  6426     def checkopt(opt):
  6591     def checkopt(opt):
  6427         if opts.get(opt):
  6592         if opts.get(opt):
  6428             for i, allowable in allowables:
  6593             for i, allowable in allowables:
  6429                 if opts[i] and opt not in allowable:
  6594                 if opts[i] and opt not in allowable:
  6430                     raise error.Abort(
  6595                     raise error.Abort(
  6431                         _(
  6596                         _(
  6432                             "options '--%s' and '--%s' may not be "
  6597                             b"options '--%s' and '--%s' may not be "
  6433                             "used together"
  6598                             b"used together"
  6434                         )
  6599                         )
  6435                         % (opt, i)
  6600                         % (opt, i)
  6436                     )
  6601                     )
  6437             return True
  6602             return True
  6438 
  6603 
  6439     if checkopt('cleanup'):
  6604     if checkopt(b'cleanup'):
  6440         if pats:
  6605         if pats:
  6441             raise error.Abort(_("cannot specify names when using '--cleanup'"))
  6606             raise error.Abort(_(b"cannot specify names when using '--cleanup'"))
  6442         return shelvemod.cleanupcmd(ui, repo)
  6607         return shelvemod.cleanupcmd(ui, repo)
  6443     elif checkopt('delete'):
  6608     elif checkopt(b'delete'):
  6444         return shelvemod.deletecmd(ui, repo, pats)
  6609         return shelvemod.deletecmd(ui, repo, pats)
  6445     elif checkopt('list'):
  6610     elif checkopt(b'list'):
  6446         return shelvemod.listcmd(ui, repo, pats, opts)
  6611         return shelvemod.listcmd(ui, repo, pats, opts)
  6447     elif checkopt('patch') or checkopt('stat'):
  6612     elif checkopt(b'patch') or checkopt(b'stat'):
  6448         return shelvemod.patchcmds(ui, repo, pats, opts)
  6613         return shelvemod.patchcmds(ui, repo, pats, opts)
  6449     else:
  6614     else:
  6450         return shelvemod.createcmd(ui, repo, pats, opts)
  6615         return shelvemod.createcmd(ui, repo, pats, opts)
  6451 
  6616 
  6452 
  6617 
  6453 _NOTTERSE = 'nothing'
  6618 _NOTTERSE = b'nothing'
  6454 
  6619 
  6455 
  6620 
  6456 @command(
  6621 @command(
  6457     'status|st',
  6622     b'status|st',
  6458     [
  6623     [
  6459         ('A', 'all', None, _('show status of all files')),
  6624         (b'A', b'all', None, _(b'show status of all files')),
  6460         ('m', 'modified', None, _('show only modified files')),
  6625         (b'm', b'modified', None, _(b'show only modified files')),
  6461         ('a', 'added', None, _('show only added files')),
  6626         (b'a', b'added', None, _(b'show only added files')),
  6462         ('r', 'removed', None, _('show only removed files')),
  6627         (b'r', b'removed', None, _(b'show only removed files')),
  6463         ('d', 'deleted', None, _('show only deleted (but tracked) files')),
  6628         (b'd', b'deleted', None, _(b'show only deleted (but tracked) files')),
  6464         ('c', 'clean', None, _('show only files without changes')),
  6629         (b'c', b'clean', None, _(b'show only files without changes')),
  6465         ('u', 'unknown', None, _('show only unknown (not tracked) files')),
  6630         (b'u', b'unknown', None, _(b'show only unknown (not tracked) files')),
  6466         ('i', 'ignored', None, _('show only ignored files')),
  6631         (b'i', b'ignored', None, _(b'show only ignored files')),
  6467         ('n', 'no-status', None, _('hide status prefix')),
  6632         (b'n', b'no-status', None, _(b'hide status prefix')),
  6468         ('t', 'terse', _NOTTERSE, _('show the terse output (EXPERIMENTAL)')),
  6633         (b't', b'terse', _NOTTERSE, _(b'show the terse output (EXPERIMENTAL)')),
  6469         ('C', 'copies', None, _('show source of copied files')),
  6634         (b'C', b'copies', None, _(b'show source of copied files')),
  6470         ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
  6635         (
  6471         ('', 'rev', [], _('show difference from revision'), _('REV')),
  6636             b'0',
  6472         ('', 'change', '', _('list the changed files of a revision'), _('REV')),
  6637             b'print0',
       
  6638             None,
       
  6639             _(b'end filenames with NUL, for use with xargs'),
       
  6640         ),
       
  6641         (b'', b'rev', [], _(b'show difference from revision'), _(b'REV')),
       
  6642         (
       
  6643             b'',
       
  6644             b'change',
       
  6645             b'',
       
  6646             _(b'list the changed files of a revision'),
       
  6647             _(b'REV'),
       
  6648         ),
  6473     ]
  6649     ]
  6474     + walkopts
  6650     + walkopts
  6475     + subrepoopts
  6651     + subrepoopts
  6476     + formatteropts,
  6652     + formatteropts,
  6477     _('[OPTION]... [FILE]...'),
  6653     _(b'[OPTION]... [FILE]...'),
  6478     helpcategory=command.CATEGORY_WORKING_DIRECTORY,
  6654     helpcategory=command.CATEGORY_WORKING_DIRECTORY,
  6479     helpbasic=True,
  6655     helpbasic=True,
  6480     inferrepo=True,
  6656     inferrepo=True,
  6481     intents={INTENT_READONLY},
  6657     intents={INTENT_READONLY},
  6482 )
  6658 )
  6574     Returns 0 on success.
  6750     Returns 0 on success.
  6575 
  6751 
  6576     """
  6752     """
  6577 
  6753 
  6578     opts = pycompat.byteskwargs(opts)
  6754     opts = pycompat.byteskwargs(opts)
  6579     revs = opts.get('rev')
  6755     revs = opts.get(b'rev')
  6580     change = opts.get('change')
  6756     change = opts.get(b'change')
  6581     terse = opts.get('terse')
  6757     terse = opts.get(b'terse')
  6582     if terse is _NOTTERSE:
  6758     if terse is _NOTTERSE:
  6583         if revs:
  6759         if revs:
  6584             terse = ''
  6760             terse = b''
  6585         else:
  6761         else:
  6586             terse = ui.config('commands', 'status.terse')
  6762             terse = ui.config(b'commands', b'status.terse')
  6587 
  6763 
  6588     if revs and change:
  6764     if revs and change:
  6589         msg = _('cannot specify --rev and --change at the same time')
  6765         msg = _(b'cannot specify --rev and --change at the same time')
  6590         raise error.Abort(msg)
  6766         raise error.Abort(msg)
  6591     elif revs and terse:
  6767     elif revs and terse:
  6592         msg = _('cannot use --terse with --rev')
  6768         msg = _(b'cannot use --terse with --rev')
  6593         raise error.Abort(msg)
  6769         raise error.Abort(msg)
  6594     elif change:
  6770     elif change:
  6595         repo = scmutil.unhidehashlikerevs(repo, [change], 'nowarn')
  6771         repo = scmutil.unhidehashlikerevs(repo, [change], b'nowarn')
  6596         ctx2 = scmutil.revsingle(repo, change, None)
  6772         ctx2 = scmutil.revsingle(repo, change, None)
  6597         ctx1 = ctx2.p1()
  6773         ctx1 = ctx2.p1()
  6598     else:
  6774     else:
  6599         repo = scmutil.unhidehashlikerevs(repo, revs, 'nowarn')
  6775         repo = scmutil.unhidehashlikerevs(repo, revs, b'nowarn')
  6600         ctx1, ctx2 = scmutil.revpair(repo, revs)
  6776         ctx1, ctx2 = scmutil.revpair(repo, revs)
  6601 
  6777 
  6602     forcerelativevalue = None
  6778     forcerelativevalue = None
  6603     if ui.hasconfig('commands', 'status.relative'):
  6779     if ui.hasconfig(b'commands', b'status.relative'):
  6604         forcerelativevalue = ui.configbool('commands', 'status.relative')
  6780         forcerelativevalue = ui.configbool(b'commands', b'status.relative')
  6605     uipathfn = scmutil.getuipathfn(
  6781     uipathfn = scmutil.getuipathfn(
  6606         repo,
  6782         repo,
  6607         legacyrelativevalue=bool(pats),
  6783         legacyrelativevalue=bool(pats),
  6608         forcerelativevalue=forcerelativevalue,
  6784         forcerelativevalue=forcerelativevalue,
  6609     )
  6785     )
  6610 
  6786 
  6611     if opts.get('print0'):
  6787     if opts.get(b'print0'):
  6612         end = '\0'
  6788         end = b'\0'
  6613     else:
  6789     else:
  6614         end = '\n'
  6790         end = b'\n'
  6615     copy = {}
  6791     copy = {}
  6616     states = 'modified added removed deleted unknown ignored clean'.split()
  6792     states = b'modified added removed deleted unknown ignored clean'.split()
  6617     show = [k for k in states if opts.get(k)]
  6793     show = [k for k in states if opts.get(k)]
  6618     if opts.get('all'):
  6794     if opts.get(b'all'):
  6619         show += ui.quiet and (states[:4] + ['clean']) or states
  6795         show += ui.quiet and (states[:4] + [b'clean']) or states
  6620 
  6796 
  6621     if not show:
  6797     if not show:
  6622         if ui.quiet:
  6798         if ui.quiet:
  6623             show = states[:4]
  6799             show = states[:4]
  6624         else:
  6800         else:
  6629         # we need to compute clean and unknown to terse
  6805         # we need to compute clean and unknown to terse
  6630         stat = repo.status(
  6806         stat = repo.status(
  6631             ctx1.node(),
  6807             ctx1.node(),
  6632             ctx2.node(),
  6808             ctx2.node(),
  6633             m,
  6809             m,
  6634             'ignored' in show or 'i' in terse,
  6810             b'ignored' in show or b'i' in terse,
  6635             clean=True,
  6811             clean=True,
  6636             unknown=True,
  6812             unknown=True,
  6637             listsubrepos=opts.get('subrepos'),
  6813             listsubrepos=opts.get(b'subrepos'),
  6638         )
  6814         )
  6639 
  6815 
  6640         stat = cmdutil.tersedir(stat, terse)
  6816         stat = cmdutil.tersedir(stat, terse)
  6641     else:
  6817     else:
  6642         stat = repo.status(
  6818         stat = repo.status(
  6643             ctx1.node(),
  6819             ctx1.node(),
  6644             ctx2.node(),
  6820             ctx2.node(),
  6645             m,
  6821             m,
  6646             'ignored' in show,
  6822             b'ignored' in show,
  6647             'clean' in show,
  6823             b'clean' in show,
  6648             'unknown' in show,
  6824             b'unknown' in show,
  6649             opts.get('subrepos'),
  6825             opts.get(b'subrepos'),
  6650         )
  6826         )
  6651 
  6827 
  6652     changestates = zip(states, pycompat.iterbytestr('MAR!?IC'), stat)
  6828     changestates = zip(states, pycompat.iterbytestr(b'MAR!?IC'), stat)
  6653 
  6829 
  6654     if (
  6830     if (
  6655         opts.get('all')
  6831         opts.get(b'all')
  6656         or opts.get('copies')
  6832         or opts.get(b'copies')
  6657         or ui.configbool('ui', 'statuscopies')
  6833         or ui.configbool(b'ui', b'statuscopies')
  6658     ) and not opts.get('no_status'):
  6834     ) and not opts.get(b'no_status'):
  6659         copy = copies.pathcopies(ctx1, ctx2, m)
  6835         copy = copies.pathcopies(ctx1, ctx2, m)
  6660 
  6836 
  6661     ui.pager('status')
  6837     ui.pager(b'status')
  6662     fm = ui.formatter('status', opts)
  6838     fm = ui.formatter(b'status', opts)
  6663     fmt = '%s' + end
  6839     fmt = b'%s' + end
  6664     showchar = not opts.get('no_status')
  6840     showchar = not opts.get(b'no_status')
  6665 
  6841 
  6666     for state, char, files in changestates:
  6842     for state, char, files in changestates:
  6667         if state in show:
  6843         if state in show:
  6668             label = 'status.' + state
  6844             label = b'status.' + state
  6669             for f in files:
  6845             for f in files:
  6670                 fm.startitem()
  6846                 fm.startitem()
  6671                 fm.context(ctx=ctx2)
  6847                 fm.context(ctx=ctx2)
  6672                 fm.data(path=f)
  6848                 fm.data(path=f)
  6673                 fm.condwrite(showchar, 'status', '%s ', char, label=label)
  6849                 fm.condwrite(showchar, b'status', b'%s ', char, label=label)
  6674                 fm.plain(fmt % uipathfn(f), label=label)
  6850                 fm.plain(fmt % uipathfn(f), label=label)
  6675                 if f in copy:
  6851                 if f in copy:
  6676                     fm.data(source=copy[f])
  6852                     fm.data(source=copy[f])
  6677                     fm.plain(
  6853                     fm.plain(
  6678                         ('  %s' + end) % uipathfn(copy[f]),
  6854                         (b'  %s' + end) % uipathfn(copy[f]),
  6679                         label='status.copied',
  6855                         label=b'status.copied',
  6680                     )
  6856                     )
  6681 
  6857 
  6682     if (
  6858     if (
  6683         ui.verbose or ui.configbool('commands', 'status.verbose')
  6859         ui.verbose or ui.configbool(b'commands', b'status.verbose')
  6684     ) and not ui.plain():
  6860     ) and not ui.plain():
  6685         cmdutil.morestatus(repo, fm)
  6861         cmdutil.morestatus(repo, fm)
  6686     fm.end()
  6862     fm.end()
  6687 
  6863 
  6688 
  6864 
  6689 @command(
  6865 @command(
  6690     'summary|sum',
  6866     b'summary|sum',
  6691     [('', 'remote', None, _('check for push and pull'))],
  6867     [(b'', b'remote', None, _(b'check for push and pull'))],
  6692     '[--remote]',
  6868     b'[--remote]',
  6693     helpcategory=command.CATEGORY_WORKING_DIRECTORY,
  6869     helpcategory=command.CATEGORY_WORKING_DIRECTORY,
  6694     helpbasic=True,
  6870     helpbasic=True,
  6695     intents={INTENT_READONLY},
  6871     intents={INTENT_READONLY},
  6696 )
  6872 )
  6697 def summary(ui, repo, **opts):
  6873 def summary(ui, repo, **opts):
  6705 
  6881 
  6706     Returns 0 on success.
  6882     Returns 0 on success.
  6707     """
  6883     """
  6708 
  6884 
  6709     opts = pycompat.byteskwargs(opts)
  6885     opts = pycompat.byteskwargs(opts)
  6710     ui.pager('summary')
  6886     ui.pager(b'summary')
  6711     ctx = repo[None]
  6887     ctx = repo[None]
  6712     parents = ctx.parents()
  6888     parents = ctx.parents()
  6713     pnode = parents[0].node()
  6889     pnode = parents[0].node()
  6714     marks = []
  6890     marks = []
  6715 
  6891 
  6716     try:
  6892     try:
  6717         ms = mergemod.mergestate.read(repo)
  6893         ms = mergemod.mergestate.read(repo)
  6718     except error.UnsupportedMergeRecords as e:
  6894     except error.UnsupportedMergeRecords as e:
  6719         s = ' '.join(e.recordtypes)
  6895         s = b' '.join(e.recordtypes)
  6720         ui.warn(
  6896         ui.warn(
  6721             _('warning: merge state has unsupported record types: %s\n') % s
  6897             _(b'warning: merge state has unsupported record types: %s\n') % s
  6722         )
  6898         )
  6723         unresolved = []
  6899         unresolved = []
  6724     else:
  6900     else:
  6725         unresolved = list(ms.unresolved())
  6901         unresolved = list(ms.unresolved())
  6726 
  6902 
  6727     for p in parents:
  6903     for p in parents:
  6728         # label with log.changeset (instead of log.parent) since this
  6904         # label with log.changeset (instead of log.parent) since this
  6729         # shows a working directory parent *changeset*:
  6905         # shows a working directory parent *changeset*:
  6730         # i18n: column positioning for "hg summary"
  6906         # i18n: column positioning for "hg summary"
  6731         ui.write(
  6907         ui.write(
  6732             _('parent: %d:%s ') % (p.rev(), p),
  6908             _(b'parent: %d:%s ') % (p.rev(), p),
  6733             label=logcmdutil.changesetlabels(p),
  6909             label=logcmdutil.changesetlabels(p),
  6734         )
  6910         )
  6735         ui.write(' '.join(p.tags()), label='log.tag')
  6911         ui.write(b' '.join(p.tags()), label=b'log.tag')
  6736         if p.bookmarks():
  6912         if p.bookmarks():
  6737             marks.extend(p.bookmarks())
  6913             marks.extend(p.bookmarks())
  6738         if p.rev() == -1:
  6914         if p.rev() == -1:
  6739             if not len(repo):
  6915             if not len(repo):
  6740                 ui.write(_(' (empty repository)'))
  6916                 ui.write(_(b' (empty repository)'))
  6741             else:
  6917             else:
  6742                 ui.write(_(' (no revision checked out)'))
  6918                 ui.write(_(b' (no revision checked out)'))
  6743         if p.obsolete():
  6919         if p.obsolete():
  6744             ui.write(_(' (obsolete)'))
  6920             ui.write(_(b' (obsolete)'))
  6745         if p.isunstable():
  6921         if p.isunstable():
  6746             instabilities = (
  6922             instabilities = (
  6747                 ui.label(instability, 'trouble.%s' % instability)
  6923                 ui.label(instability, b'trouble.%s' % instability)
  6748                 for instability in p.instabilities()
  6924                 for instability in p.instabilities()
  6749             )
  6925             )
  6750             ui.write(' (' + ', '.join(instabilities) + ')')
  6926             ui.write(b' (' + b', '.join(instabilities) + b')')
  6751         ui.write('\n')
  6927         ui.write(b'\n')
  6752         if p.description():
  6928         if p.description():
  6753             ui.status(
  6929             ui.status(
  6754                 ' ' + p.description().splitlines()[0].strip() + '\n',
  6930                 b' ' + p.description().splitlines()[0].strip() + b'\n',
  6755                 label='log.summary',
  6931                 label=b'log.summary',
  6756             )
  6932             )
  6757 
  6933 
  6758     branch = ctx.branch()
  6934     branch = ctx.branch()
  6759     bheads = repo.branchheads(branch)
  6935     bheads = repo.branchheads(branch)
  6760     # i18n: column positioning for "hg summary"
  6936     # i18n: column positioning for "hg summary"
  6761     m = _('branch: %s\n') % branch
  6937     m = _(b'branch: %s\n') % branch
  6762     if branch != 'default':
  6938     if branch != b'default':
  6763         ui.write(m, label='log.branch')
  6939         ui.write(m, label=b'log.branch')
  6764     else:
  6940     else:
  6765         ui.status(m, label='log.branch')
  6941         ui.status(m, label=b'log.branch')
  6766 
  6942 
  6767     if marks:
  6943     if marks:
  6768         active = repo._activebookmark
  6944         active = repo._activebookmark
  6769         # i18n: column positioning for "hg summary"
  6945         # i18n: column positioning for "hg summary"
  6770         ui.write(_('bookmarks:'), label='log.bookmark')
  6946         ui.write(_(b'bookmarks:'), label=b'log.bookmark')
  6771         if active is not None:
  6947         if active is not None:
  6772             if active in marks:
  6948             if active in marks:
  6773                 ui.write(' *' + active, label=bookmarks.activebookmarklabel)
  6949                 ui.write(b' *' + active, label=bookmarks.activebookmarklabel)
  6774                 marks.remove(active)
  6950                 marks.remove(active)
  6775             else:
  6951             else:
  6776                 ui.write(' [%s]' % active, label=bookmarks.activebookmarklabel)
  6952                 ui.write(b' [%s]' % active, label=bookmarks.activebookmarklabel)
  6777         for m in marks:
  6953         for m in marks:
  6778             ui.write(' ' + m, label='log.bookmark')
  6954             ui.write(b' ' + m, label=b'log.bookmark')
  6779         ui.write('\n', label='log.bookmark')
  6955         ui.write(b'\n', label=b'log.bookmark')
  6780 
  6956 
  6781     status = repo.status(unknown=True)
  6957     status = repo.status(unknown=True)
  6782 
  6958 
  6783     c = repo.dirstate.copies()
  6959     c = repo.dirstate.copies()
  6784     copied, renamed = [], []
  6960     copied, renamed = [], []
  6792             status.added.remove(d)
  6968             status.added.remove(d)
  6793 
  6969 
  6794     subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
  6970     subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
  6795 
  6971 
  6796     labels = [
  6972     labels = [
  6797         (ui.label(_('%d modified'), 'status.modified'), status.modified),
  6973         (ui.label(_(b'%d modified'), b'status.modified'), status.modified),
  6798         (ui.label(_('%d added'), 'status.added'), status.added),
  6974         (ui.label(_(b'%d added'), b'status.added'), status.added),
  6799         (ui.label(_('%d removed'), 'status.removed'), status.removed),
  6975         (ui.label(_(b'%d removed'), b'status.removed'), status.removed),
  6800         (ui.label(_('%d renamed'), 'status.copied'), renamed),
  6976         (ui.label(_(b'%d renamed'), b'status.copied'), renamed),
  6801         (ui.label(_('%d copied'), 'status.copied'), copied),
  6977         (ui.label(_(b'%d copied'), b'status.copied'), copied),
  6802         (ui.label(_('%d deleted'), 'status.deleted'), status.deleted),
  6978         (ui.label(_(b'%d deleted'), b'status.deleted'), status.deleted),
  6803         (ui.label(_('%d unknown'), 'status.unknown'), status.unknown),
  6979         (ui.label(_(b'%d unknown'), b'status.unknown'), status.unknown),
  6804         (ui.label(_('%d unresolved'), 'resolve.unresolved'), unresolved),
  6980         (ui.label(_(b'%d unresolved'), b'resolve.unresolved'), unresolved),
  6805         (ui.label(_('%d subrepos'), 'status.modified'), subs),
  6981         (ui.label(_(b'%d subrepos'), b'status.modified'), subs),
  6806     ]
  6982     ]
  6807     t = []
  6983     t = []
  6808     for l, s in labels:
  6984     for l, s in labels:
  6809         if s:
  6985         if s:
  6810             t.append(l % len(s))
  6986             t.append(l % len(s))
  6811 
  6987 
  6812     t = ', '.join(t)
  6988     t = b', '.join(t)
  6813     cleanworkdir = False
  6989     cleanworkdir = False
  6814 
  6990 
  6815     if repo.vfs.exists('graftstate'):
  6991     if repo.vfs.exists(b'graftstate'):
  6816         t += _(' (graft in progress)')
  6992         t += _(b' (graft in progress)')
  6817     if repo.vfs.exists('updatestate'):
  6993     if repo.vfs.exists(b'updatestate'):
  6818         t += _(' (interrupted update)')
  6994         t += _(b' (interrupted update)')
  6819     elif len(parents) > 1:
  6995     elif len(parents) > 1:
  6820         t += _(' (merge)')
  6996         t += _(b' (merge)')
  6821     elif branch != parents[0].branch():
  6997     elif branch != parents[0].branch():
  6822         t += _(' (new branch)')
  6998         t += _(b' (new branch)')
  6823     elif parents[0].closesbranch() and pnode in repo.branchheads(
  6999     elif parents[0].closesbranch() and pnode in repo.branchheads(
  6824         branch, closed=True
  7000         branch, closed=True
  6825     ):
  7001     ):
  6826         t += _(' (head closed)')
  7002         t += _(b' (head closed)')
  6827     elif not (
  7003     elif not (
  6828         status.modified
  7004         status.modified
  6829         or status.added
  7005         or status.added
  6830         or status.removed
  7006         or status.removed
  6831         or renamed
  7007         or renamed
  6832         or copied
  7008         or copied
  6833         or subs
  7009         or subs
  6834     ):
  7010     ):
  6835         t += _(' (clean)')
  7011         t += _(b' (clean)')
  6836         cleanworkdir = True
  7012         cleanworkdir = True
  6837     elif pnode not in bheads:
  7013     elif pnode not in bheads:
  6838         t += _(' (new branch head)')
  7014         t += _(b' (new branch head)')
  6839 
  7015 
  6840     if parents:
  7016     if parents:
  6841         pendingphase = max(p.phase() for p in parents)
  7017         pendingphase = max(p.phase() for p in parents)
  6842     else:
  7018     else:
  6843         pendingphase = phases.public
  7019         pendingphase = phases.public
  6844 
  7020 
  6845     if pendingphase > phases.newcommitphase(ui):
  7021     if pendingphase > phases.newcommitphase(ui):
  6846         t += ' (%s)' % phases.phasenames[pendingphase]
  7022         t += b' (%s)' % phases.phasenames[pendingphase]
  6847 
  7023 
  6848     if cleanworkdir:
  7024     if cleanworkdir:
  6849         # i18n: column positioning for "hg summary"
  7025         # i18n: column positioning for "hg summary"
  6850         ui.status(_('commit: %s\n') % t.strip())
  7026         ui.status(_(b'commit: %s\n') % t.strip())
  6851     else:
  7027     else:
  6852         # i18n: column positioning for "hg summary"
  7028         # i18n: column positioning for "hg summary"
  6853         ui.write(_('commit: %s\n') % t.strip())
  7029         ui.write(_(b'commit: %s\n') % t.strip())
  6854 
  7030 
  6855     # all ancestors of branch heads - all ancestors of parent = new csets
  7031     # all ancestors of branch heads - all ancestors of parent = new csets
  6856     new = len(
  7032     new = len(
  6857         repo.changelog.findmissing([pctx.node() for pctx in parents], bheads)
  7033         repo.changelog.findmissing([pctx.node() for pctx in parents], bheads)
  6858     )
  7034     )
  6859 
  7035 
  6860     if new == 0:
  7036     if new == 0:
  6861         # i18n: column positioning for "hg summary"
  7037         # i18n: column positioning for "hg summary"
  6862         ui.status(_('update: (current)\n'))
  7038         ui.status(_(b'update: (current)\n'))
  6863     elif pnode not in bheads:
  7039     elif pnode not in bheads:
  6864         # i18n: column positioning for "hg summary"
  7040         # i18n: column positioning for "hg summary"
  6865         ui.write(_('update: %d new changesets (update)\n') % new)
  7041         ui.write(_(b'update: %d new changesets (update)\n') % new)
  6866     else:
  7042     else:
  6867         # i18n: column positioning for "hg summary"
  7043         # i18n: column positioning for "hg summary"
  6868         ui.write(
  7044         ui.write(
  6869             _('update: %d new changesets, %d branch heads (merge)\n')
  7045             _(b'update: %d new changesets, %d branch heads (merge)\n')
  6870             % (new, len(bheads))
  7046             % (new, len(bheads))
  6871         )
  7047         )
  6872 
  7048 
  6873     t = []
  7049     t = []
  6874     draft = len(repo.revs('draft()'))
  7050     draft = len(repo.revs(b'draft()'))
  6875     if draft:
  7051     if draft:
  6876         t.append(_('%d draft') % draft)
  7052         t.append(_(b'%d draft') % draft)
  6877     secret = len(repo.revs('secret()'))
  7053     secret = len(repo.revs(b'secret()'))
  6878     if secret:
  7054     if secret:
  6879         t.append(_('%d secret') % secret)
  7055         t.append(_(b'%d secret') % secret)
  6880 
  7056 
  6881     if draft or secret:
  7057     if draft or secret:
  6882         ui.status(_('phases: %s\n') % ', '.join(t))
  7058         ui.status(_(b'phases: %s\n') % b', '.join(t))
  6883 
  7059 
  6884     if obsolete.isenabled(repo, obsolete.createmarkersopt):
  7060     if obsolete.isenabled(repo, obsolete.createmarkersopt):
  6885         for trouble in ("orphan", "contentdivergent", "phasedivergent"):
  7061         for trouble in (b"orphan", b"contentdivergent", b"phasedivergent"):
  6886             numtrouble = len(repo.revs(trouble + "()"))
  7062             numtrouble = len(repo.revs(trouble + b"()"))
  6887             # We write all the possibilities to ease translation
  7063             # We write all the possibilities to ease translation
  6888             troublemsg = {
  7064             troublemsg = {
  6889                 "orphan": _("orphan: %d changesets"),
  7065                 b"orphan": _(b"orphan: %d changesets"),
  6890                 "contentdivergent": _("content-divergent: %d changesets"),
  7066                 b"contentdivergent": _(b"content-divergent: %d changesets"),
  6891                 "phasedivergent": _("phase-divergent: %d changesets"),
  7067                 b"phasedivergent": _(b"phase-divergent: %d changesets"),
  6892             }
  7068             }
  6893             if numtrouble > 0:
  7069             if numtrouble > 0:
  6894                 ui.status(troublemsg[trouble] % numtrouble + "\n")
  7070                 ui.status(troublemsg[trouble] % numtrouble + b"\n")
  6895 
  7071 
  6896     cmdutil.summaryhooks(ui, repo)
  7072     cmdutil.summaryhooks(ui, repo)
  6897 
  7073 
  6898     if opts.get('remote'):
  7074     if opts.get(b'remote'):
  6899         needsincoming, needsoutgoing = True, True
  7075         needsincoming, needsoutgoing = True, True
  6900     else:
  7076     else:
  6901         needsincoming, needsoutgoing = False, False
  7077         needsincoming, needsoutgoing = False, False
  6902         for i, o in cmdutil.summaryremotehooks(ui, repo, opts, None):
  7078         for i, o in cmdutil.summaryremotehooks(ui, repo, opts, None):
  6903             if i:
  7079             if i:
  6906                 needsoutgoing = True
  7082                 needsoutgoing = True
  6907         if not needsincoming and not needsoutgoing:
  7083         if not needsincoming and not needsoutgoing:
  6908             return
  7084             return
  6909 
  7085 
  6910     def getincoming():
  7086     def getincoming():
  6911         source, branches = hg.parseurl(ui.expandpath('default'))
  7087         source, branches = hg.parseurl(ui.expandpath(b'default'))
  6912         sbranch = branches[0]
  7088         sbranch = branches[0]
  6913         try:
  7089         try:
  6914             other = hg.peer(repo, {}, source)
  7090             other = hg.peer(repo, {}, source)
  6915         except error.RepoError:
  7091         except error.RepoError:
  6916             if opts.get('remote'):
  7092             if opts.get(b'remote'):
  6917                 raise
  7093                 raise
  6918             return source, sbranch, None, None, None
  7094             return source, sbranch, None, None, None
  6919         revs, checkout = hg.addbranchrevs(repo, other, branches, None)
  7095         revs, checkout = hg.addbranchrevs(repo, other, branches, None)
  6920         if revs:
  7096         if revs:
  6921             revs = [other.lookup(rev) for rev in revs]
  7097             revs = [other.lookup(rev) for rev in revs]
  6922         ui.debug('comparing with %s\n' % util.hidepassword(source))
  7098         ui.debug(b'comparing with %s\n' % util.hidepassword(source))
  6923         repo.ui.pushbuffer()
  7099         repo.ui.pushbuffer()
  6924         commoninc = discovery.findcommonincoming(repo, other, heads=revs)
  7100         commoninc = discovery.findcommonincoming(repo, other, heads=revs)
  6925         repo.ui.popbuffer()
  7101         repo.ui.popbuffer()
  6926         return source, sbranch, other, commoninc, commoninc[1]
  7102         return source, sbranch, other, commoninc, commoninc[1]
  6927 
  7103 
  6929         source, sbranch, sother, commoninc, incoming = getincoming()
  7105         source, sbranch, sother, commoninc, incoming = getincoming()
  6930     else:
  7106     else:
  6931         source = sbranch = sother = commoninc = incoming = None
  7107         source = sbranch = sother = commoninc = incoming = None
  6932 
  7108 
  6933     def getoutgoing():
  7109     def getoutgoing():
  6934         dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
  7110         dest, branches = hg.parseurl(ui.expandpath(b'default-push', b'default'))
  6935         dbranch = branches[0]
  7111         dbranch = branches[0]
  6936         revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
  7112         revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
  6937         if source != dest:
  7113         if source != dest:
  6938             try:
  7114             try:
  6939                 dother = hg.peer(repo, {}, dest)
  7115                 dother = hg.peer(repo, {}, dest)
  6940             except error.RepoError:
  7116             except error.RepoError:
  6941                 if opts.get('remote'):
  7117                 if opts.get(b'remote'):
  6942                     raise
  7118                     raise
  6943                 return dest, dbranch, None, None
  7119                 return dest, dbranch, None, None
  6944             ui.debug('comparing with %s\n' % util.hidepassword(dest))
  7120             ui.debug(b'comparing with %s\n' % util.hidepassword(dest))
  6945         elif sother is None:
  7121         elif sother is None:
  6946             # there is no explicit destination peer, but source one is invalid
  7122             # there is no explicit destination peer, but source one is invalid
  6947             return dest, dbranch, None, None
  7123             return dest, dbranch, None, None
  6948         else:
  7124         else:
  6949             dother = sother
  7125             dother = sother
  6963     if needsoutgoing:
  7139     if needsoutgoing:
  6964         dest, dbranch, dother, outgoing = getoutgoing()
  7140         dest, dbranch, dother, outgoing = getoutgoing()
  6965     else:
  7141     else:
  6966         dest = dbranch = dother = outgoing = None
  7142         dest = dbranch = dother = outgoing = None
  6967 
  7143 
  6968     if opts.get('remote'):
  7144     if opts.get(b'remote'):
  6969         t = []
  7145         t = []
  6970         if incoming:
  7146         if incoming:
  6971             t.append(_('1 or more incoming'))
  7147             t.append(_(b'1 or more incoming'))
  6972         o = outgoing.missing
  7148         o = outgoing.missing
  6973         if o:
  7149         if o:
  6974             t.append(_('%d outgoing') % len(o))
  7150             t.append(_(b'%d outgoing') % len(o))
  6975         other = dother or sother
  7151         other = dother or sother
  6976         if 'bookmarks' in other.listkeys('namespaces'):
  7152         if b'bookmarks' in other.listkeys(b'namespaces'):
  6977             counts = bookmarks.summary(repo, other)
  7153             counts = bookmarks.summary(repo, other)
  6978             if counts[0] > 0:
  7154             if counts[0] > 0:
  6979                 t.append(_('%d incoming bookmarks') % counts[0])
  7155                 t.append(_(b'%d incoming bookmarks') % counts[0])
  6980             if counts[1] > 0:
  7156             if counts[1] > 0:
  6981                 t.append(_('%d outgoing bookmarks') % counts[1])
  7157                 t.append(_(b'%d outgoing bookmarks') % counts[1])
  6982 
  7158 
  6983         if t:
  7159         if t:
  6984             # i18n: column positioning for "hg summary"
  7160             # i18n: column positioning for "hg summary"
  6985             ui.write(_('remote: %s\n') % (', '.join(t)))
  7161             ui.write(_(b'remote: %s\n') % (b', '.join(t)))
  6986         else:
  7162         else:
  6987             # i18n: column positioning for "hg summary"
  7163             # i18n: column positioning for "hg summary"
  6988             ui.status(_('remote: (synced)\n'))
  7164             ui.status(_(b'remote: (synced)\n'))
  6989 
  7165 
  6990     cmdutil.summaryremotehooks(
  7166     cmdutil.summaryremotehooks(
  6991         ui,
  7167         ui,
  6992         repo,
  7168         repo,
  6993         opts,
  7169         opts,
  6997         ),
  7173         ),
  6998     )
  7174     )
  6999 
  7175 
  7000 
  7176 
  7001 @command(
  7177 @command(
  7002     'tag',
  7178     b'tag',
  7003     [
  7179     [
  7004         ('f', 'force', None, _('force tag')),
  7180         (b'f', b'force', None, _(b'force tag')),
  7005         ('l', 'local', None, _('make the tag local')),
  7181         (b'l', b'local', None, _(b'make the tag local')),
  7006         ('r', 'rev', '', _('revision to tag'), _('REV')),
  7182         (b'r', b'rev', b'', _(b'revision to tag'), _(b'REV')),
  7007         ('', 'remove', None, _('remove a tag')),
  7183         (b'', b'remove', None, _(b'remove a tag')),
  7008         # -l/--local is already there, commitopts cannot be used
  7184         # -l/--local is already there, commitopts cannot be used
  7009         ('e', 'edit', None, _('invoke editor on commit messages')),
  7185         (b'e', b'edit', None, _(b'invoke editor on commit messages')),
  7010         ('m', 'message', '', _('use text as commit message'), _('TEXT')),
  7186         (b'm', b'message', b'', _(b'use text as commit message'), _(b'TEXT')),
  7011     ]
  7187     ]
  7012     + commitopts2,
  7188     + commitopts2,
  7013     _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'),
  7189     _(b'[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'),
  7014     helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
  7190     helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
  7015 )
  7191 )
  7016 def tag(ui, repo, name1, *names, **opts):
  7192 def tag(ui, repo, name1, *names, **opts):
  7017     """add one or more tags for the current or given revision
  7193     """add one or more tags for the current or given revision
  7018 
  7194 
  7045 
  7221 
  7046     Returns 0 on success.
  7222     Returns 0 on success.
  7047     """
  7223     """
  7048     opts = pycompat.byteskwargs(opts)
  7224     opts = pycompat.byteskwargs(opts)
  7049     with repo.wlock(), repo.lock():
  7225     with repo.wlock(), repo.lock():
  7050         rev_ = "."
  7226         rev_ = b"."
  7051         names = [t.strip() for t in (name1,) + names]
  7227         names = [t.strip() for t in (name1,) + names]
  7052         if len(names) != len(set(names)):
  7228         if len(names) != len(set(names)):
  7053             raise error.Abort(_('tag names must be unique'))
  7229             raise error.Abort(_(b'tag names must be unique'))
  7054         for n in names:
  7230         for n in names:
  7055             scmutil.checknewlabel(repo, n, 'tag')
  7231             scmutil.checknewlabel(repo, n, b'tag')
  7056             if not n:
  7232             if not n:
  7057                 raise error.Abort(
  7233                 raise error.Abort(
  7058                     _('tag names cannot consist entirely of ' 'whitespace')
  7234                     _(b'tag names cannot consist entirely of ' b'whitespace')
  7059                 )
  7235                 )
  7060         if opts.get('rev') and opts.get('remove'):
  7236         if opts.get(b'rev') and opts.get(b'remove'):
  7061             raise error.Abort(_("--rev and --remove are incompatible"))
  7237             raise error.Abort(_(b"--rev and --remove are incompatible"))
  7062         if opts.get('rev'):
  7238         if opts.get(b'rev'):
  7063             rev_ = opts['rev']
  7239             rev_ = opts[b'rev']
  7064         message = opts.get('message')
  7240         message = opts.get(b'message')
  7065         if opts.get('remove'):
  7241         if opts.get(b'remove'):
  7066             if opts.get('local'):
  7242             if opts.get(b'local'):
  7067                 expectedtype = 'local'
  7243                 expectedtype = b'local'
  7068             else:
  7244             else:
  7069                 expectedtype = 'global'
  7245                 expectedtype = b'global'
  7070 
  7246 
  7071             for n in names:
  7247             for n in names:
  7072                 if repo.tagtype(n) == 'global':
  7248                 if repo.tagtype(n) == b'global':
  7073                     alltags = tagsmod.findglobaltags(ui, repo)
  7249                     alltags = tagsmod.findglobaltags(ui, repo)
  7074                     if alltags[n][0] == nullid:
  7250                     if alltags[n][0] == nullid:
  7075                         raise error.Abort(_("tag '%s' is already removed") % n)
  7251                         raise error.Abort(_(b"tag '%s' is already removed") % n)
  7076                 if not repo.tagtype(n):
  7252                 if not repo.tagtype(n):
  7077                     raise error.Abort(_("tag '%s' does not exist") % n)
  7253                     raise error.Abort(_(b"tag '%s' does not exist") % n)
  7078                 if repo.tagtype(n) != expectedtype:
  7254                 if repo.tagtype(n) != expectedtype:
  7079                     if expectedtype == 'global':
  7255                     if expectedtype == b'global':
  7080                         raise error.Abort(_("tag '%s' is not a global tag") % n)
  7256                         raise error.Abort(
       
  7257                             _(b"tag '%s' is not a global tag") % n
       
  7258                         )
  7081                     else:
  7259                     else:
  7082                         raise error.Abort(_("tag '%s' is not a local tag") % n)
  7260                         raise error.Abort(_(b"tag '%s' is not a local tag") % n)
  7083             rev_ = 'null'
  7261             rev_ = b'null'
  7084             if not message:
  7262             if not message:
  7085                 # we don't translate commit messages
  7263                 # we don't translate commit messages
  7086                 message = 'Removed tag %s' % ', '.join(names)
  7264                 message = b'Removed tag %s' % b', '.join(names)
  7087         elif not opts.get('force'):
  7265         elif not opts.get(b'force'):
  7088             for n in names:
  7266             for n in names:
  7089                 if n in repo.tags():
  7267                 if n in repo.tags():
  7090                     raise error.Abort(
  7268                     raise error.Abort(
  7091                         _("tag '%s' already exists " "(use -f to force)") % n
  7269                         _(b"tag '%s' already exists " b"(use -f to force)") % n
  7092                     )
  7270                     )
  7093         if not opts.get('local'):
  7271         if not opts.get(b'local'):
  7094             p1, p2 = repo.dirstate.parents()
  7272             p1, p2 = repo.dirstate.parents()
  7095             if p2 != nullid:
  7273             if p2 != nullid:
  7096                 raise error.Abort(_('uncommitted merge'))
  7274                 raise error.Abort(_(b'uncommitted merge'))
  7097             bheads = repo.branchheads()
  7275             bheads = repo.branchheads()
  7098             if not opts.get('force') and bheads and p1 not in bheads:
  7276             if not opts.get(b'force') and bheads and p1 not in bheads:
  7099                 raise error.Abort(
  7277                 raise error.Abort(
  7100                     _(
  7278                     _(
  7101                         'working directory is not at a branch head '
  7279                         b'working directory is not at a branch head '
  7102                         '(use -f to force)'
  7280                         b'(use -f to force)'
  7103                     )
  7281                     )
  7104                 )
  7282                 )
  7105         node = scmutil.revsingle(repo, rev_).node()
  7283         node = scmutil.revsingle(repo, rev_).node()
  7106 
  7284 
  7107         if not message:
  7285         if not message:
  7108             # we don't translate commit messages
  7286             # we don't translate commit messages
  7109             message = 'Added tag %s for changeset %s' % (
  7287             message = b'Added tag %s for changeset %s' % (
  7110                 ', '.join(names),
  7288                 b', '.join(names),
  7111                 short(node),
  7289                 short(node),
  7112             )
  7290             )
  7113 
  7291 
  7114         date = opts.get('date')
  7292         date = opts.get(b'date')
  7115         if date:
  7293         if date:
  7116             date = dateutil.parsedate(date)
  7294             date = dateutil.parsedate(date)
  7117 
  7295 
  7118         if opts.get('remove'):
  7296         if opts.get(b'remove'):
  7119             editform = 'tag.remove'
  7297             editform = b'tag.remove'
  7120         else:
  7298         else:
  7121             editform = 'tag.add'
  7299             editform = b'tag.add'
  7122         editor = cmdutil.getcommiteditor(
  7300         editor = cmdutil.getcommiteditor(
  7123             editform=editform, **pycompat.strkwargs(opts)
  7301             editform=editform, **pycompat.strkwargs(opts)
  7124         )
  7302         )
  7125 
  7303 
  7126         # don't allow tagging the null rev
  7304         # don't allow tagging the null rev
  7127         if (
  7305         if (
  7128             not opts.get('remove')
  7306             not opts.get(b'remove')
  7129             and scmutil.revsingle(repo, rev_).rev() == nullrev
  7307             and scmutil.revsingle(repo, rev_).rev() == nullrev
  7130         ):
  7308         ):
  7131             raise error.Abort(_("cannot tag null revision"))
  7309             raise error.Abort(_(b"cannot tag null revision"))
  7132 
  7310 
  7133         tagsmod.tag(
  7311         tagsmod.tag(
  7134             repo,
  7312             repo,
  7135             names,
  7313             names,
  7136             node,
  7314             node,
  7137             message,
  7315             message,
  7138             opts.get('local'),
  7316             opts.get(b'local'),
  7139             opts.get('user'),
  7317             opts.get(b'user'),
  7140             date,
  7318             date,
  7141             editor=editor,
  7319             editor=editor,
  7142         )
  7320         )
  7143 
  7321 
  7144 
  7322 
  7145 @command(
  7323 @command(
  7146     'tags',
  7324     b'tags',
  7147     formatteropts,
  7325     formatteropts,
  7148     '',
  7326     b'',
  7149     helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
  7327     helpcategory=command.CATEGORY_CHANGE_ORGANIZATION,
  7150     intents={INTENT_READONLY},
  7328     intents={INTENT_READONLY},
  7151 )
  7329 )
  7152 def tags(ui, repo, **opts):
  7330 def tags(ui, repo, **opts):
  7153     """list repository tags
  7331     """list repository tags
  7168 
  7346 
  7169     Returns 0 on success.
  7347     Returns 0 on success.
  7170     """
  7348     """
  7171 
  7349 
  7172     opts = pycompat.byteskwargs(opts)
  7350     opts = pycompat.byteskwargs(opts)
  7173     ui.pager('tags')
  7351     ui.pager(b'tags')
  7174     fm = ui.formatter('tags', opts)
  7352     fm = ui.formatter(b'tags', opts)
  7175     hexfunc = fm.hexfunc
  7353     hexfunc = fm.hexfunc
  7176 
  7354 
  7177     for t, n in reversed(repo.tagslist()):
  7355     for t, n in reversed(repo.tagslist()):
  7178         hn = hexfunc(n)
  7356         hn = hexfunc(n)
  7179         label = 'tags.normal'
  7357         label = b'tags.normal'
  7180         tagtype = ''
  7358         tagtype = b''
  7181         if repo.tagtype(t) == 'local':
  7359         if repo.tagtype(t) == b'local':
  7182             label = 'tags.local'
  7360             label = b'tags.local'
  7183             tagtype = 'local'
  7361             tagtype = b'local'
  7184 
  7362 
  7185         fm.startitem()
  7363         fm.startitem()
  7186         fm.context(repo=repo)
  7364         fm.context(repo=repo)
  7187         fm.write('tag', '%s', t, label=label)
  7365         fm.write(b'tag', b'%s', t, label=label)
  7188         fmt = " " * (30 - encoding.colwidth(t)) + ' %5d:%s'
  7366         fmt = b" " * (30 - encoding.colwidth(t)) + b' %5d:%s'
  7189         fm.condwrite(
  7367         fm.condwrite(
  7190             not ui.quiet,
  7368             not ui.quiet,
  7191             'rev node',
  7369             b'rev node',
  7192             fmt,
  7370             fmt,
  7193             repo.changelog.rev(n),
  7371             repo.changelog.rev(n),
  7194             hn,
  7372             hn,
  7195             label=label,
  7373             label=label,
  7196         )
  7374         )
  7197         fm.condwrite(
  7375         fm.condwrite(
  7198             ui.verbose and tagtype, 'type', ' %s', tagtype, label=label
  7376             ui.verbose and tagtype, b'type', b' %s', tagtype, label=label
  7199         )
  7377         )
  7200         fm.plain('\n')
  7378         fm.plain(b'\n')
  7201     fm.end()
  7379     fm.end()
  7202 
  7380 
  7203 
  7381 
  7204 @command(
  7382 @command(
  7205     'tip',
  7383     b'tip',
  7206     [
  7384     [
  7207         ('p', 'patch', None, _('show patch')),
  7385         (b'p', b'patch', None, _(b'show patch')),
  7208         ('g', 'git', None, _('use git extended diff format')),
  7386         (b'g', b'git', None, _(b'use git extended diff format')),
  7209     ]
  7387     ]
  7210     + templateopts,
  7388     + templateopts,
  7211     _('[-p] [-g]'),
  7389     _(b'[-p] [-g]'),
  7212     helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
  7390     helpcategory=command.CATEGORY_CHANGE_NAVIGATION,
  7213 )
  7391 )
  7214 def tip(ui, repo, **opts):
  7392 def tip(ui, repo, **opts):
  7215     """show the tip revision (DEPRECATED)
  7393     """show the tip revision (DEPRECATED)
  7216 
  7394 
  7227 
  7405 
  7228     Returns 0 on success.
  7406     Returns 0 on success.
  7229     """
  7407     """
  7230     opts = pycompat.byteskwargs(opts)
  7408     opts = pycompat.byteskwargs(opts)
  7231     displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
  7409     displayer = logcmdutil.changesetdisplayer(ui, repo, opts)
  7232     displayer.show(repo['tip'])
  7410     displayer.show(repo[b'tip'])
  7233     displayer.close()
  7411     displayer.close()
  7234 
  7412 
  7235 
  7413 
  7236 @command(
  7414 @command(
  7237     'unbundle',
  7415     b'unbundle',
  7238     [
  7416     [
  7239         (
  7417         (
  7240             'u',
  7418             b'u',
  7241             'update',
  7419             b'update',
  7242             None,
  7420             None,
  7243             _('update to new branch head if changesets were unbundled'),
  7421             _(b'update to new branch head if changesets were unbundled'),
  7244         )
  7422         )
  7245     ],
  7423     ],
  7246     _('[-u] FILE...'),
  7424     _(b'[-u] FILE...'),
  7247     helpcategory=command.CATEGORY_IMPORT_EXPORT,
  7425     helpcategory=command.CATEGORY_IMPORT_EXPORT,
  7248 )
  7426 )
  7249 def unbundle(ui, repo, fname1, *fnames, **opts):
  7427 def unbundle(ui, repo, fname1, *fnames, **opts):
  7250     """apply one or more bundle files
  7428     """apply one or more bundle files
  7251 
  7429 
  7259         for fname in fnames:
  7437         for fname in fnames:
  7260             f = hg.openpath(ui, fname)
  7438             f = hg.openpath(ui, fname)
  7261             gen = exchange.readbundle(ui, f, fname)
  7439             gen = exchange.readbundle(ui, f, fname)
  7262             if isinstance(gen, streamclone.streamcloneapplier):
  7440             if isinstance(gen, streamclone.streamcloneapplier):
  7263                 raise error.Abort(
  7441                 raise error.Abort(
  7264                     _('packed bundles cannot be applied with ' '"hg unbundle"'),
  7442                     _(
  7265                     hint=_('use "hg debugapplystreamclonebundle"'),
  7443                         b'packed bundles cannot be applied with '
       
  7444                         b'"hg unbundle"'
       
  7445                     ),
       
  7446                     hint=_(b'use "hg debugapplystreamclonebundle"'),
  7266                 )
  7447                 )
  7267             url = 'bundle:' + fname
  7448             url = b'bundle:' + fname
  7268             try:
  7449             try:
  7269                 txnname = 'unbundle'
  7450                 txnname = b'unbundle'
  7270                 if not isinstance(gen, bundle2.unbundle20):
  7451                 if not isinstance(gen, bundle2.unbundle20):
  7271                     txnname = 'unbundle\n%s' % util.hidepassword(url)
  7452                     txnname = b'unbundle\n%s' % util.hidepassword(url)
  7272                 with repo.transaction(txnname) as tr:
  7453                 with repo.transaction(txnname) as tr:
  7273                     op = bundle2.applybundle(
  7454                     op = bundle2.applybundle(
  7274                         repo, gen, tr, source='unbundle', url=url
  7455                         repo, gen, tr, source=b'unbundle', url=url
  7275                     )
  7456                     )
  7276             except error.BundleUnknownFeatureError as exc:
  7457             except error.BundleUnknownFeatureError as exc:
  7277                 raise error.Abort(
  7458                 raise error.Abort(
  7278                     _('%s: unknown bundle feature, %s') % (fname, exc),
  7459                     _(b'%s: unknown bundle feature, %s') % (fname, exc),
  7279                     hint=_(
  7460                     hint=_(
  7280                         "see https://mercurial-scm.org/"
  7461                         b"see https://mercurial-scm.org/"
  7281                         "wiki/BundleFeature for more "
  7462                         b"wiki/BundleFeature for more "
  7282                         "information"
  7463                         b"information"
  7283                     ),
  7464                     ),
  7284                 )
  7465                 )
  7285             modheads = bundle2.combinechangegroupresults(op)
  7466             modheads = bundle2.combinechangegroupresults(op)
  7286 
  7467 
  7287     return postincoming(ui, repo, modheads, opts.get(r'update'), None, None)
  7468     return postincoming(ui, repo, modheads, opts.get(r'update'), None, None)
  7288 
  7469 
  7289 
  7470 
  7290 @command(
  7471 @command(
  7291     'unshelve',
  7472     b'unshelve',
  7292     [
  7473     [
  7293         ('a', 'abort', None, _('abort an incomplete unshelve operation')),
  7474         (b'a', b'abort', None, _(b'abort an incomplete unshelve operation')),
  7294         ('c', 'continue', None, _('continue an incomplete unshelve operation')),
  7475         (
  7295         ('i', 'interactive', None, _('use interactive mode (EXPERIMENTAL)')),
  7476             b'c',
  7296         ('k', 'keep', None, _('keep shelve after unshelving')),
  7477             b'continue',
  7297         (
  7478             None,
  7298             'n',
  7479             _(b'continue an incomplete unshelve operation'),
  7299             'name',
  7480         ),
  7300             '',
  7481         (b'i', b'interactive', None, _(b'use interactive mode (EXPERIMENTAL)')),
  7301             _('restore shelved change with given name'),
  7482         (b'k', b'keep', None, _(b'keep shelve after unshelving')),
  7302             _('NAME'),
  7483         (
  7303         ),
  7484             b'n',
  7304         ('t', 'tool', '', _('specify merge tool')),
  7485             b'name',
  7305         (
  7486             b'',
  7306             '',
  7487             _(b'restore shelved change with given name'),
  7307             'date',
  7488             _(b'NAME'),
  7308             '',
  7489         ),
  7309             _('set date for temporary commits (DEPRECATED)'),
  7490         (b't', b'tool', b'', _(b'specify merge tool')),
  7310             _('DATE'),
  7491         (
       
  7492             b'',
       
  7493             b'date',
       
  7494             b'',
       
  7495             _(b'set date for temporary commits (DEPRECATED)'),
       
  7496             _(b'DATE'),
  7311         ),
  7497         ),
  7312     ],
  7498     ],
  7313     _('hg unshelve [OPTION]... [FILE]... [-n SHELVED]'),
  7499     _(b'hg unshelve [OPTION]... [FILE]... [-n SHELVED]'),
  7314     helpcategory=command.CATEGORY_WORKING_DIRECTORY,
  7500     helpcategory=command.CATEGORY_WORKING_DIRECTORY,
  7315 )
  7501 )
  7316 def unshelve(ui, repo, *shelved, **opts):
  7502 def unshelve(ui, repo, *shelved, **opts):
  7317     """restore a shelved change to the working directory
  7503     """restore a shelved change to the working directory
  7318 
  7504 
  7360     with repo.wlock():
  7546     with repo.wlock():
  7361         return shelvemod.dounshelve(ui, repo, *shelved, **opts)
  7547         return shelvemod.dounshelve(ui, repo, *shelved, **opts)
  7362 
  7548 
  7363 
  7549 
  7364 statemod.addunfinished(
  7550 statemod.addunfinished(
  7365     'unshelve',
  7551     b'unshelve',
  7366     fname='shelvedstate',
  7552     fname=b'shelvedstate',
  7367     continueflag=True,
  7553     continueflag=True,
  7368     abortfunc=shelvemod.hgabortunshelve,
  7554     abortfunc=shelvemod.hgabortunshelve,
  7369     continuefunc=shelvemod.hgcontinueunshelve,
  7555     continuefunc=shelvemod.hgcontinueunshelve,
  7370     cmdmsg=_('unshelve already in progress'),
  7556     cmdmsg=_(b'unshelve already in progress'),
  7371 )
  7557 )
  7372 
  7558 
  7373 
  7559 
  7374 @command(
  7560 @command(
  7375     'update|up|checkout|co',
  7561     b'update|up|checkout|co',
  7376     [
  7562     [
  7377         ('C', 'clean', None, _('discard uncommitted changes (no backup)')),
  7563         (b'C', b'clean', None, _(b'discard uncommitted changes (no backup)')),
  7378         ('c', 'check', None, _('require clean working directory')),
  7564         (b'c', b'check', None, _(b'require clean working directory')),
  7379         ('m', 'merge', None, _('merge uncommitted changes')),
  7565         (b'm', b'merge', None, _(b'merge uncommitted changes')),
  7380         ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
  7566         (b'd', b'date', b'', _(b'tipmost revision matching date'), _(b'DATE')),
  7381         ('r', 'rev', '', _('revision'), _('REV')),
  7567         (b'r', b'rev', b'', _(b'revision'), _(b'REV')),
  7382     ]
  7568     ]
  7383     + mergetoolopts,
  7569     + mergetoolopts,
  7384     _('[-C|-c|-m] [-d DATE] [[-r] REV]'),
  7570     _(b'[-C|-c|-m] [-d DATE] [[-r] REV]'),
  7385     helpcategory=command.CATEGORY_WORKING_DIRECTORY,
  7571     helpcategory=command.CATEGORY_WORKING_DIRECTORY,
  7386     helpbasic=True,
  7572     helpbasic=True,
  7387 )
  7573 )
  7388 def update(ui, repo, node=None, **opts):
  7574 def update(ui, repo, node=None, **opts):
  7389     """update working directory (or switch revisions)
  7575     """update working directory (or switch revisions)
  7444     date = opts.get(r'date')
  7630     date = opts.get(r'date')
  7445     clean = opts.get(r'clean')
  7631     clean = opts.get(r'clean')
  7446     check = opts.get(r'check')
  7632     check = opts.get(r'check')
  7447     merge = opts.get(r'merge')
  7633     merge = opts.get(r'merge')
  7448     if rev and node:
  7634     if rev and node:
  7449         raise error.Abort(_("please specify just one revision"))
  7635         raise error.Abort(_(b"please specify just one revision"))
  7450 
  7636 
  7451     if ui.configbool('commands', 'update.requiredest'):
  7637     if ui.configbool(b'commands', b'update.requiredest'):
  7452         if not node and not rev and not date:
  7638         if not node and not rev and not date:
  7453             raise error.Abort(
  7639             raise error.Abort(
  7454                 _('you must specify a destination'),
  7640                 _(b'you must specify a destination'),
  7455                 hint=_('for example: hg update ".::"'),
  7641                 hint=_(b'for example: hg update ".::"'),
  7456             )
  7642             )
  7457 
  7643 
  7458     if rev is None or rev == '':
  7644     if rev is None or rev == b'':
  7459         rev = node
  7645         rev = node
  7460 
  7646 
  7461     if date and rev is not None:
  7647     if date and rev is not None:
  7462         raise error.Abort(_("you can't specify a revision and a date"))
  7648         raise error.Abort(_(b"you can't specify a revision and a date"))
  7463 
  7649 
  7464     if len([x for x in (clean, check, merge) if x]) > 1:
  7650     if len([x for x in (clean, check, merge) if x]) > 1:
  7465         raise error.Abort(
  7651         raise error.Abort(
  7466             _(
  7652             _(
  7467                 "can only specify one of -C/--clean, -c/--check, "
  7653                 b"can only specify one of -C/--clean, -c/--check, "
  7468                 "or -m/--merge"
  7654                 b"or -m/--merge"
  7469             )
  7655             )
  7470         )
  7656         )
  7471 
  7657 
  7472     updatecheck = None
  7658     updatecheck = None
  7473     if check:
  7659     if check:
  7474         updatecheck = 'abort'
  7660         updatecheck = b'abort'
  7475     elif merge:
  7661     elif merge:
  7476         updatecheck = 'none'
  7662         updatecheck = b'none'
  7477 
  7663 
  7478     with repo.wlock():
  7664     with repo.wlock():
  7479         cmdutil.clearunfinished(repo)
  7665         cmdutil.clearunfinished(repo)
  7480         if date:
  7666         if date:
  7481             rev = cmdutil.finddate(ui, repo, date)
  7667             rev = cmdutil.finddate(ui, repo, date)
  7482 
  7668 
  7483         # if we defined a bookmark, we have to remember the original name
  7669         # if we defined a bookmark, we have to remember the original name
  7484         brev = rev
  7670         brev = rev
  7485         if rev:
  7671         if rev:
  7486             repo = scmutil.unhidehashlikerevs(repo, [rev], 'nowarn')
  7672             repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
  7487         ctx = scmutil.revsingle(repo, rev, default=None)
  7673         ctx = scmutil.revsingle(repo, rev, default=None)
  7488         rev = ctx.rev()
  7674         rev = ctx.rev()
  7489         hidden = ctx.hidden()
  7675         hidden = ctx.hidden()
  7490         overrides = {('ui', 'forcemerge'): opts.get(r'tool', '')}
  7676         overrides = {(b'ui', b'forcemerge'): opts.get(r'tool', b'')}
  7491         with ui.configoverride(overrides, 'update'):
  7677         with ui.configoverride(overrides, b'update'):
  7492             ret = hg.updatetotally(
  7678             ret = hg.updatetotally(
  7493                 ui, repo, rev, brev, clean=clean, updatecheck=updatecheck
  7679                 ui, repo, rev, brev, clean=clean, updatecheck=updatecheck
  7494             )
  7680             )
  7495         if hidden:
  7681         if hidden:
  7496             ctxstr = ctx.hex()[:12]
  7682             ctxstr = ctx.hex()[:12]
  7497             ui.warn(_("updated to hidden changeset %s\n") % ctxstr)
  7683             ui.warn(_(b"updated to hidden changeset %s\n") % ctxstr)
  7498 
  7684 
  7499             if ctx.obsolete():
  7685             if ctx.obsolete():
  7500                 obsfatemsg = obsutil._getfilteredreason(repo, ctxstr, ctx)
  7686                 obsfatemsg = obsutil._getfilteredreason(repo, ctxstr, ctx)
  7501                 ui.warn("(%s)\n" % obsfatemsg)
  7687                 ui.warn(b"(%s)\n" % obsfatemsg)
  7502         return ret
  7688         return ret
  7503 
  7689 
  7504 
  7690 
  7505 @command(
  7691 @command(
  7506     'verify',
  7692     b'verify',
  7507     [('', 'full', False, 'perform more checks (EXPERIMENTAL)')],
  7693     [(b'', b'full', False, b'perform more checks (EXPERIMENTAL)')],
  7508     helpcategory=command.CATEGORY_MAINTENANCE,
  7694     helpcategory=command.CATEGORY_MAINTENANCE,
  7509 )
  7695 )
  7510 def verify(ui, repo, **opts):
  7696 def verify(ui, repo, **opts):
  7511     """verify the integrity of the repository
  7697     """verify the integrity of the repository
  7512 
  7698 
  7524     Returns 0 on success, 1 if errors are encountered.
  7710     Returns 0 on success, 1 if errors are encountered.
  7525     """
  7711     """
  7526     opts = pycompat.byteskwargs(opts)
  7712     opts = pycompat.byteskwargs(opts)
  7527 
  7713 
  7528     level = None
  7714     level = None
  7529     if opts['full']:
  7715     if opts[b'full']:
  7530         level = verifymod.VERIFY_FULL
  7716         level = verifymod.VERIFY_FULL
  7531     return hg.verify(repo, level)
  7717     return hg.verify(repo, level)
  7532 
  7718 
  7533 
  7719 
  7534 @command(
  7720 @command(
  7535     'version',
  7721     b'version',
  7536     [] + formatteropts,
  7722     [] + formatteropts,
  7537     helpcategory=command.CATEGORY_HELP,
  7723     helpcategory=command.CATEGORY_HELP,
  7538     norepo=True,
  7724     norepo=True,
  7539     intents={INTENT_READONLY},
  7725     intents={INTENT_READONLY},
  7540 )
  7726 )
  7556       :bundled: Boolean. True if included in the release.
  7742       :bundled: Boolean. True if included in the release.
  7557       :name:    String. Extension name.
  7743       :name:    String. Extension name.
  7558     """
  7744     """
  7559     opts = pycompat.byteskwargs(opts)
  7745     opts = pycompat.byteskwargs(opts)
  7560     if ui.verbose:
  7746     if ui.verbose:
  7561         ui.pager('version')
  7747         ui.pager(b'version')
  7562     fm = ui.formatter("version", opts)
  7748     fm = ui.formatter(b"version", opts)
  7563     fm.startitem()
  7749     fm.startitem()
  7564     fm.write(
  7750     fm.write(
  7565         "ver", _("Mercurial Distributed SCM (version %s)\n"), util.version()
  7751         b"ver", _(b"Mercurial Distributed SCM (version %s)\n"), util.version()
  7566     )
  7752     )
  7567     license = _(
  7753     license = _(
  7568         "(see https://mercurial-scm.org for more information)\n"
  7754         b"(see https://mercurial-scm.org for more information)\n"
  7569         "\nCopyright (C) 2005-2019 Matt Mackall and others\n"
  7755         b"\nCopyright (C) 2005-2019 Matt Mackall and others\n"
  7570         "This is free software; see the source for copying conditions. "
  7756         b"This is free software; see the source for copying conditions. "
  7571         "There is NO\nwarranty; "
  7757         b"There is NO\nwarranty; "
  7572         "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
  7758         b"not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
  7573     )
  7759     )
  7574     if not ui.quiet:
  7760     if not ui.quiet:
  7575         fm.plain(license)
  7761         fm.plain(license)
  7576 
  7762 
  7577     if ui.verbose:
  7763     if ui.verbose:
  7578         fm.plain(_("\nEnabled extensions:\n\n"))
  7764         fm.plain(_(b"\nEnabled extensions:\n\n"))
  7579     # format names and versions into columns
  7765     # format names and versions into columns
  7580     names = []
  7766     names = []
  7581     vers = []
  7767     vers = []
  7582     isinternals = []
  7768     isinternals = []
  7583     for name, module in extensions.extensions():
  7769     for name, module in extensions.extensions():
  7584         names.append(name)
  7770         names.append(name)
  7585         vers.append(extensions.moduleversion(module) or None)
  7771         vers.append(extensions.moduleversion(module) or None)
  7586         isinternals.append(extensions.ismoduleinternal(module))
  7772         isinternals.append(extensions.ismoduleinternal(module))
  7587     fn = fm.nested("extensions", tmpl='{name}\n')
  7773     fn = fm.nested(b"extensions", tmpl=b'{name}\n')
  7588     if names:
  7774     if names:
  7589         namefmt = "  %%-%ds  " % max(len(n) for n in names)
  7775         namefmt = b"  %%-%ds  " % max(len(n) for n in names)
  7590         places = [_("external"), _("internal")]
  7776         places = [_(b"external"), _(b"internal")]
  7591         for n, v, p in zip(names, vers, isinternals):
  7777         for n, v, p in zip(names, vers, isinternals):
  7592             fn.startitem()
  7778             fn.startitem()
  7593             fn.condwrite(ui.verbose, "name", namefmt, n)
  7779             fn.condwrite(ui.verbose, b"name", namefmt, n)
  7594             if ui.verbose:
  7780             if ui.verbose:
  7595                 fn.plain("%s  " % places[p])
  7781                 fn.plain(b"%s  " % places[p])
  7596             fn.data(bundled=p)
  7782             fn.data(bundled=p)
  7597             fn.condwrite(ui.verbose and v, "ver", "%s", v)
  7783             fn.condwrite(ui.verbose and v, b"ver", b"%s", v)
  7598             if ui.verbose:
  7784             if ui.verbose:
  7599                 fn.plain("\n")
  7785                 fn.plain(b"\n")
  7600     fn.end()
  7786     fn.end()
  7601     fm.end()
  7787     fm.end()
  7602 
  7788 
  7603 
  7789 
  7604 def loadcmdtable(ui, name, cmdtable):
  7790 def loadcmdtable(ui, name, cmdtable):
  7605     """Load command functions from specified cmdtable
  7791     """Load command functions from specified cmdtable
  7606     """
  7792     """
  7607     overrides = [cmd for cmd in cmdtable if cmd in table]
  7793     overrides = [cmd for cmd in cmdtable if cmd in table]
  7608     if overrides:
  7794     if overrides:
  7609         ui.warn(
  7795         ui.warn(
  7610             _("extension '%s' overrides commands: %s\n")
  7796             _(b"extension '%s' overrides commands: %s\n")
  7611             % (name, " ".join(overrides))
  7797             % (name, b" ".join(overrides))
  7612         )
  7798         )
  7613     table.update(cmdtable)
  7799     table.update(cmdtable)