hgext/narrow/narrowcommands.py
changeset 43077 687b865b95ad
parent 43076 2372284d9457
child 43117 8ff1ecfadcd1
--- a/hgext/narrow/narrowcommands.py	Sun Oct 06 09:45:02 2019 -0400
+++ b/hgext/narrow/narrowcommands.py	Sun Oct 06 09:48:39 2019 -0400
@@ -39,59 +39,69 @@
 def setup():
     """Wraps user-facing mercurial commands with narrow-aware versions."""
 
-    entry = extensions.wrapcommand(commands.table, 'clone', clonenarrowcmd)
+    entry = extensions.wrapcommand(commands.table, b'clone', clonenarrowcmd)
     entry[1].append(
-        ('', 'narrow', None, _("create a narrow clone of select files"))
+        (b'', b'narrow', None, _(b"create a narrow clone of select files"))
     )
     entry[1].append(
-        ('', 'depth', '', _("limit the history fetched by distance from heads"))
+        (
+            b'',
+            b'depth',
+            b'',
+            _(b"limit the history fetched by distance from heads"),
+        )
     )
-    entry[1].append(('', 'narrowspec', '', _("read narrowspecs from file")))
+    entry[1].append((b'', b'narrowspec', b'', _(b"read narrowspecs from file")))
     # TODO(durin42): unify sparse/narrow --include/--exclude logic a bit
-    if 'sparse' not in extensions.enabled():
+    if b'sparse' not in extensions.enabled():
         entry[1].append(
-            ('', 'include', [], _("specifically fetch this file/directory"))
+            (b'', b'include', [], _(b"specifically fetch this file/directory"))
         )
         entry[1].append(
             (
-                '',
-                'exclude',
+                b'',
+                b'exclude',
                 [],
-                _("do not fetch this file/directory, even if included"),
+                _(b"do not fetch this file/directory, even if included"),
             )
         )
 
-    entry = extensions.wrapcommand(commands.table, 'pull', pullnarrowcmd)
+    entry = extensions.wrapcommand(commands.table, b'pull', pullnarrowcmd)
     entry[1].append(
-        ('', 'depth', '', _("limit the history fetched by distance from heads"))
+        (
+            b'',
+            b'depth',
+            b'',
+            _(b"limit the history fetched by distance from heads"),
+        )
     )
 
-    extensions.wrapcommand(commands.table, 'archive', archivenarrowcmd)
+    extensions.wrapcommand(commands.table, b'archive', archivenarrowcmd)
 
 
 def clonenarrowcmd(orig, ui, repo, *args, **opts):
     """Wraps clone command, so 'hg clone' first wraps localrepo.clone()."""
     opts = pycompat.byteskwargs(opts)
     wrappedextraprepare = util.nullcontextmanager()
-    narrowspecfile = opts['narrowspec']
+    narrowspecfile = opts[b'narrowspec']
 
     if narrowspecfile:
         filepath = os.path.join(encoding.getcwd(), narrowspecfile)
-        ui.status(_("reading narrowspec from '%s'\n") % filepath)
+        ui.status(_(b"reading narrowspec from '%s'\n") % filepath)
         try:
             fdata = util.readfile(filepath)
         except IOError as inst:
             raise error.Abort(
-                _("cannot read narrowspecs from '%s': %s")
+                _(b"cannot read narrowspecs from '%s': %s")
                 % (filepath, encoding.strtolocal(inst.strerror))
             )
 
-        includes, excludes, profiles = sparse.parseconfig(ui, fdata, 'narrow')
+        includes, excludes, profiles = sparse.parseconfig(ui, fdata, b'narrow')
         if profiles:
             raise error.Abort(
                 _(
-                    "cannot specify other files using '%include' in"
-                    " narrowspec"
+                    b"cannot specify other files using '%include' in"
+                    b" narrowspec"
                 )
             )
 
@@ -99,20 +109,20 @@
         narrowspec.validatepatterns(excludes)
 
         # narrowspec is passed so we should assume that user wants narrow clone
-        opts['narrow'] = True
-        opts['include'].extend(includes)
-        opts['exclude'].extend(excludes)
+        opts[b'narrow'] = True
+        opts[b'include'].extend(includes)
+        opts[b'exclude'].extend(excludes)
 
-    if opts['narrow']:
+    if opts[b'narrow']:
 
         def pullbundle2extraprepare_widen(orig, pullop, kwargs):
             orig(pullop, kwargs)
 
-            if opts.get('depth'):
-                kwargs['depth'] = opts['depth']
+            if opts.get(b'depth'):
+                kwargs[b'depth'] = opts[b'depth']
 
         wrappedextraprepare = extensions.wrappedfunction(
-            exchange, '_pullbundle2extraprepare', pullbundle2extraprepare_widen
+            exchange, b'_pullbundle2extraprepare', pullbundle2extraprepare_widen
         )
 
     with wrappedextraprepare:
@@ -127,10 +137,10 @@
         def pullbundle2extraprepare_widen(orig, pullop, kwargs):
             orig(pullop, kwargs)
             if opts.get(r'depth'):
-                kwargs['depth'] = opts[r'depth']
+                kwargs[b'depth'] = opts[r'depth']
 
         wrappedextraprepare = extensions.wrappedfunction(
-            exchange, '_pullbundle2extraprepare', pullbundle2extraprepare_widen
+            exchange, b'_pullbundle2extraprepare', pullbundle2extraprepare_widen
         )
 
     with wrappedextraprepare:
@@ -159,33 +169,33 @@
         return orig(pullop, kwargs)
 
     if wireprototypes.NARROWCAP not in pullop.remote.capabilities():
-        raise error.Abort(_("server does not support narrow clones"))
+        raise error.Abort(_(b"server does not support narrow clones"))
     orig(pullop, kwargs)
-    kwargs['narrow'] = True
+    kwargs[b'narrow'] = True
     include, exclude = repo.narrowpats
-    kwargs['oldincludepats'] = include
-    kwargs['oldexcludepats'] = exclude
+    kwargs[b'oldincludepats'] = include
+    kwargs[b'oldexcludepats'] = exclude
     if include:
-        kwargs['includepats'] = include
+        kwargs[b'includepats'] = include
     if exclude:
-        kwargs['excludepats'] = exclude
+        kwargs[b'excludepats'] = exclude
     # calculate known nodes only in ellipses cases because in non-ellipses cases
     # we have all the nodes
     if wireprototypes.ELLIPSESCAP1 in pullop.remote.capabilities():
-        kwargs['known'] = [
+        kwargs[b'known'] = [
             node.hex(ctx.node())
-            for ctx in repo.set('::%ln', pullop.common)
+            for ctx in repo.set(b'::%ln', pullop.common)
             if ctx.node() != node.nullid
         ]
-        if not kwargs['known']:
+        if not kwargs[b'known']:
             # Mercurial serializes an empty list as '' and deserializes it as
             # [''], so delete it instead to avoid handling the empty string on
             # the server.
-            del kwargs['known']
+            del kwargs[b'known']
 
 
 extensions.wrapfunction(
-    exchange, '_pullbundle2extraprepare', pullbundle2extraprepare
+    exchange, b'_pullbundle2extraprepare', pullbundle2extraprepare
 )
 
 
@@ -208,62 +218,64 @@
     # have any changes to files that will be untracked.
     unfi = repo.unfiltered()
     outgoing = discovery.findcommonoutgoing(unfi, remote, commoninc=commoninc)
-    ui.status(_('looking for local changes to affected paths\n'))
+    ui.status(_(b'looking for local changes to affected paths\n'))
     localnodes = []
     for n in itertools.chain(outgoing.missing, outgoing.excluded):
         if any(oldmatch(f) and not newmatch(f) for f in unfi[n].files()):
             localnodes.append(n)
-    revstostrip = unfi.revs('descendants(%ln)', localnodes)
-    hiddenrevs = repoview.filterrevs(repo, 'visible')
+    revstostrip = unfi.revs(b'descendants(%ln)', localnodes)
+    hiddenrevs = repoview.filterrevs(repo, b'visible')
     visibletostrip = list(
         repo.changelog.node(r) for r in (revstostrip - hiddenrevs)
     )
     if visibletostrip:
         ui.status(
             _(
-                'The following changeset(s) or their ancestors have '
-                'local changes not on the remote:\n'
+                b'The following changeset(s) or their ancestors have '
+                b'local changes not on the remote:\n'
             )
         )
         maxnodes = 10
         if ui.verbose or len(visibletostrip) <= maxnodes:
             for n in visibletostrip:
-                ui.status('%s\n' % node.short(n))
+                ui.status(b'%s\n' % node.short(n))
         else:
             for n in visibletostrip[:maxnodes]:
-                ui.status('%s\n' % node.short(n))
+                ui.status(b'%s\n' % node.short(n))
             ui.status(
-                _('...and %d more, use --verbose to list all\n')
+                _(b'...and %d more, use --verbose to list all\n')
                 % (len(visibletostrip) - maxnodes)
             )
         if not force:
             raise error.Abort(
-                _('local changes found'),
-                hint=_('use --force-delete-local-changes to ' 'ignore'),
+                _(b'local changes found'),
+                hint=_(b'use --force-delete-local-changes to ' b'ignore'),
             )
 
     with ui.uninterruptible():
         if revstostrip:
             tostrip = [unfi.changelog.node(r) for r in revstostrip]
-            if repo['.'].node() in tostrip:
+            if repo[b'.'].node() in tostrip:
                 # stripping working copy, so move to a different commit first
                 urev = max(
                     repo.revs(
-                        '(::%n) - %ln + null', repo['.'].node(), visibletostrip
+                        b'(::%n) - %ln + null',
+                        repo[b'.'].node(),
+                        visibletostrip,
                     )
                 )
                 hg.clean(repo, urev)
-            overrides = {('devel', 'strip-obsmarkers'): False}
-            with ui.configoverride(overrides, 'narrow'):
-                repair.strip(ui, unfi, tostrip, topic='narrow')
+            overrides = {(b'devel', b'strip-obsmarkers'): False}
+            with ui.configoverride(overrides, b'narrow'):
+                repair.strip(ui, unfi, tostrip, topic=b'narrow')
 
         todelete = []
         for f, f2, size in repo.store.datafiles():
-            if f.startswith('data/'):
+            if f.startswith(b'data/'):
                 file = f[5:-2]
                 if not newmatch(file):
                     todelete.append(f)
-            elif f.startswith('meta/'):
+            elif f.startswith(b'meta/'):
                 dir = f[5:-13]
                 dirs = sorted(util.dirs({dir})) + [dir]
                 include = True
@@ -272,20 +284,20 @@
                     if not visit:
                         include = False
                         break
-                    if visit == 'all':
+                    if visit == b'all':
                         break
                 if not include:
                     todelete.append(f)
 
         repo.destroying()
 
-        with repo.transaction('narrowing'):
+        with repo.transaction(b'narrowing'):
             # Update narrowspec before removing revlogs, so repo won't be
             # corrupt in case of crash
             repo.setnarrowpats(newincludes, newexcludes)
 
             for f in todelete:
-                ui.status(_('deleting %s\n') % f)
+                ui.status(_(b'deleting %s\n') % f)
                 util.unlinkpath(repo.svfs.join(f))
                 repo.store.markremoved(f)
 
@@ -327,11 +339,11 @@
     def pullbundle2extraprepare_widen(orig, pullop, kwargs):
         orig(pullop, kwargs)
         # The old{in,ex}cludepats have already been set by orig()
-        kwargs['includepats'] = newincludes
-        kwargs['excludepats'] = newexcludes
+        kwargs[b'includepats'] = newincludes
+        kwargs[b'excludepats'] = newexcludes
 
     wrappedextraprepare = extensions.wrappedfunction(
-        exchange, '_pullbundle2extraprepare', pullbundle2extraprepare_widen
+        exchange, b'_pullbundle2extraprepare', pullbundle2extraprepare_widen
     )
 
     # define a function that narrowbundle2 can call after creating the
@@ -341,7 +353,7 @@
 
     repo.setnewnarrowpats = setnewnarrowpats
     # silence the devel-warning of applying an empty changegroup
-    overrides = {('devel', 'all-warnings'): False}
+    overrides = {(b'devel', b'all-warnings'): False}
 
     common = commoninc[0]
     with ui.uninterruptible():
@@ -358,28 +370,30 @@
             if ellipsesremote:
                 known = [
                     ctx.node()
-                    for ctx in repo.set('::%ln', common)
+                    for ctx in repo.set(b'::%ln', common)
                     if ctx.node() != node.nullid
                 ]
             with remote.commandexecutor() as e:
                 bundle = e.callcommand(
-                    'narrow_widen',
+                    b'narrow_widen',
                     {
-                        'oldincludes': oldincludes,
-                        'oldexcludes': oldexcludes,
-                        'newincludes': newincludes,
-                        'newexcludes': newexcludes,
-                        'cgversion': '03',
-                        'commonheads': common,
-                        'known': known,
-                        'ellipses': ellipsesremote,
+                        b'oldincludes': oldincludes,
+                        b'oldexcludes': oldexcludes,
+                        b'newincludes': newincludes,
+                        b'newexcludes': newexcludes,
+                        b'cgversion': b'03',
+                        b'commonheads': common,
+                        b'known': known,
+                        b'ellipses': ellipsesremote,
                     },
                 ).result()
 
-            trmanager = exchange.transactionmanager(repo, 'widen', remote.url())
-            with trmanager, repo.ui.configoverride(overrides, 'widen'):
+            trmanager = exchange.transactionmanager(
+                repo, b'widen', remote.url()
+            )
+            with trmanager, repo.ui.configoverride(overrides, b'widen'):
                 op = bundle2.bundleoperation(
-                    repo, trmanager.transaction, source='widen'
+                    repo, trmanager.transaction, source=b'widen'
                 )
                 # TODO: we should catch error.Abort here
                 bundle2.processbundle(repo, bundle, op=op)
@@ -388,7 +402,7 @@
             with ds.parentchange():
                 ds.setparents(p1, p2)
 
-        with repo.transaction('widening'):
+        with repo.transaction(b'widening'):
             repo.setnewnarrowpats()
             narrowspec.updateworkingcopy(repo)
             narrowspec.copytoworkingcopy(repo)
@@ -396,35 +410,40 @@
 
 # TODO(rdamazio): Make new matcher format and update description
 @command(
-    'tracked',
+    b'tracked',
     [
-        ('', 'addinclude', [], _('new paths to include')),
-        ('', 'removeinclude', [], _('old paths to no longer include')),
+        (b'', b'addinclude', [], _(b'new paths to include')),
+        (b'', b'removeinclude', [], _(b'old paths to no longer include')),
         (
-            '',
-            'auto-remove-includes',
+            b'',
+            b'auto-remove-includes',
             False,
-            _('automatically choose unused includes to remove'),
+            _(b'automatically choose unused includes to remove'),
         ),
-        ('', 'addexclude', [], _('new paths to exclude')),
-        ('', 'import-rules', '', _('import narrowspecs from a file')),
-        ('', 'removeexclude', [], _('old paths to no longer exclude')),
-        ('', 'clear', False, _('whether to replace the existing narrowspec')),
+        (b'', b'addexclude', [], _(b'new paths to exclude')),
+        (b'', b'import-rules', b'', _(b'import narrowspecs from a file')),
+        (b'', b'removeexclude', [], _(b'old paths to no longer exclude')),
         (
-            '',
-            'force-delete-local-changes',
+            b'',
+            b'clear',
             False,
-            _('forces deletion of local changes when narrowing'),
+            _(b'whether to replace the existing narrowspec'),
         ),
         (
-            '',
-            'update-working-copy',
+            b'',
+            b'force-delete-local-changes',
             False,
-            _('update working copy when the store has changed'),
+            _(b'forces deletion of local changes when narrowing'),
+        ),
+        (
+            b'',
+            b'update-working-copy',
+            False,
+            _(b'update working copy when the store has changed'),
         ),
     ]
     + commands.remoteopts,
-    _('[OPTIONS]... [REMOTE]'),
+    _(b'[OPTIONS]... [REMOTE]'),
     inferrepo=True,
 )
 def trackedcmd(ui, repo, remotepath=None, *pats, **opts):
@@ -464,47 +483,47 @@
     if repository.NARROW_REQUIREMENT not in repo.requirements:
         raise error.Abort(
             _(
-                'the tracked command is only supported on '
-                'repositories cloned with --narrow'
+                b'the tracked command is only supported on '
+                b'repositories cloned with --narrow'
             )
         )
 
     # Before supporting, decide whether it "hg tracked --clear" should mean
     # tracking no paths or all paths.
-    if opts['clear']:
-        raise error.Abort(_('the --clear option is not yet supported'))
+    if opts[b'clear']:
+        raise error.Abort(_(b'the --clear option is not yet supported'))
 
     # import rules from a file
-    newrules = opts.get('import_rules')
+    newrules = opts.get(b'import_rules')
     if newrules:
         try:
             filepath = os.path.join(encoding.getcwd(), newrules)
             fdata = util.readfile(filepath)
         except IOError as inst:
             raise error.Abort(
-                _("cannot read narrowspecs from '%s': %s")
+                _(b"cannot read narrowspecs from '%s': %s")
                 % (filepath, encoding.strtolocal(inst.strerror))
             )
         includepats, excludepats, profiles = sparse.parseconfig(
-            ui, fdata, 'narrow'
+            ui, fdata, b'narrow'
         )
         if profiles:
             raise error.Abort(
                 _(
-                    "including other spec files using '%include' "
-                    "is not supported in narrowspec"
+                    b"including other spec files using '%include' "
+                    b"is not supported in narrowspec"
                 )
             )
-        opts['addinclude'].extend(includepats)
-        opts['addexclude'].extend(excludepats)
+        opts[b'addinclude'].extend(includepats)
+        opts[b'addexclude'].extend(excludepats)
 
-    addedincludes = narrowspec.parsepatterns(opts['addinclude'])
-    removedincludes = narrowspec.parsepatterns(opts['removeinclude'])
-    addedexcludes = narrowspec.parsepatterns(opts['addexclude'])
-    removedexcludes = narrowspec.parsepatterns(opts['removeexclude'])
-    autoremoveincludes = opts['auto_remove_includes']
+    addedincludes = narrowspec.parsepatterns(opts[b'addinclude'])
+    removedincludes = narrowspec.parsepatterns(opts[b'removeinclude'])
+    addedexcludes = narrowspec.parsepatterns(opts[b'addexclude'])
+    removedexcludes = narrowspec.parsepatterns(opts[b'removeexclude'])
+    autoremoveincludes = opts[b'auto_remove_includes']
 
-    update_working_copy = opts['update_working_copy']
+    update_working_copy = opts[b'update_working_copy']
     only_show = not (
         addedincludes
         or removedincludes
@@ -529,27 +548,27 @@
 
     # Only print the current narrowspec.
     if only_show:
-        ui.pager('tracked')
-        fm = ui.formatter('narrow', opts)
+        ui.pager(b'tracked')
+        fm = ui.formatter(b'narrow', opts)
         for i in sorted(oldincludes):
             fm.startitem()
-            fm.write('status', '%s ', 'I', label='narrow.included')
-            fm.write('pat', '%s\n', i, label='narrow.included')
+            fm.write(b'status', b'%s ', b'I', label=b'narrow.included')
+            fm.write(b'pat', b'%s\n', i, label=b'narrow.included')
         for i in sorted(oldexcludes):
             fm.startitem()
-            fm.write('status', '%s ', 'X', label='narrow.excluded')
-            fm.write('pat', '%s\n', i, label='narrow.excluded')
+            fm.write(b'status', b'%s ', b'X', label=b'narrow.excluded')
+            fm.write(b'pat', b'%s\n', i, label=b'narrow.excluded')
         fm.end()
         return 0
 
     if update_working_copy:
-        with repo.wlock(), repo.lock(), repo.transaction('narrow-wc'):
+        with repo.wlock(), repo.lock(), repo.transaction(b'narrow-wc'):
             narrowspec.updateworkingcopy(repo)
             narrowspec.copytoworkingcopy(repo)
         return 0
 
     if not (widening or narrowing or autoremoveincludes):
-        ui.status(_("nothing to widen or narrow\n"))
+        ui.status(_(b"nothing to widen or narrow\n"))
         return 0
 
     with repo.wlock(), repo.lock():
@@ -558,16 +577,16 @@
         # Find the revisions we have in common with the remote. These will
         # be used for finding local-only changes for narrowing. They will
         # also define the set of revisions to update for widening.
-        remotepath = ui.expandpath(remotepath or 'default')
+        remotepath = ui.expandpath(remotepath or b'default')
         url, branches = hg.parseurl(remotepath)
-        ui.status(_('comparing with %s\n') % util.hidepassword(url))
+        ui.status(_(b'comparing with %s\n') % util.hidepassword(url))
         remote = hg.peer(repo, opts, url)
 
         # check narrow support before doing anything if widening needs to be
         # performed. In future we should also abort if client is ellipses and
         # server does not support ellipses
         if widening and wireprototypes.NARROWCAP not in remote.capabilities():
-            raise error.Abort(_("server does not support narrow clones"))
+            raise error.Abort(_(b"server does not support narrow clones"))
 
         commoninc = discovery.findcommonincoming(repo, remote)
 
@@ -575,7 +594,7 @@
             outgoing = discovery.findcommonoutgoing(
                 repo, remote, commoninc=commoninc
             )
-            ui.status(_('looking for unused includes to remove\n'))
+            ui.status(_(b'looking for unused includes to remove\n'))
             localfiles = set()
             for n in itertools.chain(outgoing.missing, outgoing.excluded):
                 localfiles.update(repo[n].files())
@@ -586,17 +605,20 @@
                     suggestedremovals.append(include)
             if suggestedremovals:
                 for s in suggestedremovals:
-                    ui.status('%s\n' % s)
+                    ui.status(b'%s\n' % s)
                 if (
                     ui.promptchoice(
-                        _('remove these unused includes (yn)?' '$$ &Yes $$ &No')
+                        _(
+                            b'remove these unused includes (yn)?'
+                            b'$$ &Yes $$ &No'
+                        )
                     )
                     == 0
                 ):
                     removedincludes.update(suggestedremovals)
                     narrowing = True
             else:
-                ui.status(_('found no unused includes\n'))
+                ui.status(_(b'found no unused includes\n'))
 
         if narrowing:
             newincludes = oldincludes - removedincludes
@@ -610,7 +632,7 @@
                 oldexcludes,
                 newincludes,
                 newexcludes,
-                opts['force_delete_local_changes'],
+                opts[b'force_delete_local_changes'],
             )
             # _narrow() updated the narrowspec and _widen() below needs to
             # use the updated values as its base (otherwise removed includes