diff mercurial/cmdutil.py @ 43076:2372284d9457

formatting: blacken the codebase This is using my patch to black (https://github.com/psf/black/pull/826) so we don't un-wrap collection literals. Done with: hg files 'set:**.py - mercurial/thirdparty/** - "contrib/python-zstandard/**"' | xargs black -S # skip-blame mass-reformatting only # no-check-commit reformats foo_bar functions Differential Revision: https://phab.mercurial-scm.org/D6971
author Augie Fackler <augie@google.com>
date Sun, 06 Oct 2019 09:45:02 -0400
parents 7e9997041781
children 687b865b95ad
line wrap: on
line diff
--- a/mercurial/cmdutil.py	Sat Oct 05 10:29:34 2019 -0400
+++ b/mercurial/cmdutil.py	Sun Oct 06 09:45:02 2019 -0400
@@ -61,69 +61,81 @@
 # templates of common command options
 
 dryrunopts = [
-    ('n', 'dry-run', None,
-     _('do not perform actions, just print output')),
+    ('n', 'dry-run', None, _('do not perform actions, just print output')),
 ]
 
 confirmopts = [
-    ('', 'confirm', None,
-     _('ask before applying actions')),
+    ('', 'confirm', None, _('ask before applying actions')),
 ]
 
 remoteopts = [
-    ('e', 'ssh', '',
-     _('specify ssh command to use'), _('CMD')),
-    ('', 'remotecmd', '',
-     _('specify hg command to run on the remote side'), _('CMD')),
-    ('', 'insecure', None,
-     _('do not verify server certificate (ignoring web.cacerts config)')),
+    ('e', 'ssh', '', _('specify ssh command to use'), _('CMD')),
+    (
+        '',
+        'remotecmd',
+        '',
+        _('specify hg command to run on the remote side'),
+        _('CMD'),
+    ),
+    (
+        '',
+        'insecure',
+        None,
+        _('do not verify server certificate (ignoring web.cacerts config)'),
+    ),
 ]
 
 walkopts = [
-    ('I', 'include', [],
-     _('include names matching the given patterns'), _('PATTERN')),
-    ('X', 'exclude', [],
-     _('exclude names matching the given patterns'), _('PATTERN')),
+    (
+        'I',
+        'include',
+        [],
+        _('include names matching the given patterns'),
+        _('PATTERN'),
+    ),
+    (
+        'X',
+        'exclude',
+        [],
+        _('exclude names matching the given patterns'),
+        _('PATTERN'),
+    ),
 ]
 
 commitopts = [
-    ('m', 'message', '',
-     _('use text as commit message'), _('TEXT')),
-    ('l', 'logfile', '',
-     _('read commit message from file'), _('FILE')),
+    ('m', 'message', '', _('use text as commit message'), _('TEXT')),
+    ('l', 'logfile', '', _('read commit message from file'), _('FILE')),
 ]
 
 commitopts2 = [
-    ('d', 'date', '',
-     _('record the specified date as commit date'), _('DATE')),
-    ('u', 'user', '',
-     _('record the specified user as committer'), _('USER')),
+    ('d', 'date', '', _('record the specified date as commit date'), _('DATE')),
+    ('u', 'user', '', _('record the specified user as committer'), _('USER')),
 ]
 
 commitopts3 = [
-    (b'D', b'currentdate', None,
-     _(b'record the current date as commit date')),
-    (b'U', b'currentuser', None,
-     _(b'record the current user as committer')),
+    (b'D', b'currentdate', None, _(b'record the current date as commit date')),
+    (b'U', b'currentuser', None, _(b'record the current user as committer')),
 ]
 
 formatteropts = [
-    ('T', 'template', '',
-     _('display with template'), _('TEMPLATE')),
+    ('T', 'template', '', _('display with template'), _('TEMPLATE')),
 ]
 
 templateopts = [
-    ('', 'style', '',
-     _('display using template map file (DEPRECATED)'), _('STYLE')),
-    ('T', 'template', '',
-     _('display with template'), _('TEMPLATE')),
+    (
+        '',
+        'style',
+        '',
+        _('display using template map file (DEPRECATED)'),
+        _('STYLE'),
+    ),
+    ('T', 'template', '', _('display with template'), _('TEMPLATE')),
 ]
 
 logopts = [
     ('p', 'patch', None, _('show patch')),
     ('g', 'git', None, _('use git extended diff format')),
-    ('l', 'limit', '',
-     _('limit number of changes displayed'), _('NUM')),
+    ('l', 'limit', '', _('limit number of changes displayed'), _('NUM')),
     ('M', 'no-merges', None, _('do not show merges')),
     ('', 'stat', None, _('output diffstat-style summary of changes')),
     ('G', 'graph', None, _("show the revision DAG")),
@@ -133,44 +145,70 @@
     ('a', 'text', None, _('treat all files as text')),
     ('g', 'git', None, _('use git extended diff format')),
     ('', 'binary', None, _('generate binary diffs in git mode (default)')),
-    ('', 'nodates', None, _('omit dates from diff headers'))
+    ('', 'nodates', None, _('omit dates from diff headers')),
 ]
 
 diffwsopts = [
-    ('w', 'ignore-all-space', None,
-     _('ignore white space when comparing lines')),
-    ('b', 'ignore-space-change', None,
-     _('ignore changes in the amount of white space')),
-    ('B', 'ignore-blank-lines', None,
-     _('ignore changes whose lines are all blank')),
-    ('Z', 'ignore-space-at-eol', None,
-     _('ignore changes in whitespace at EOL')),
+    (
+        'w',
+        'ignore-all-space',
+        None,
+        _('ignore white space when comparing lines'),
+    ),
+    (
+        'b',
+        'ignore-space-change',
+        None,
+        _('ignore changes in the amount of white space'),
+    ),
+    (
+        'B',
+        'ignore-blank-lines',
+        None,
+        _('ignore changes whose lines are all blank'),
+    ),
+    (
+        'Z',
+        'ignore-space-at-eol',
+        None,
+        _('ignore changes in whitespace at EOL'),
+    ),
 ]
 
-diffopts2 = [
-    ('', 'noprefix', None, _('omit a/ and b/ prefixes from filenames')),
-    ('p', 'show-function', None, _('show which function each change is in')),
-    ('', 'reverse', None, _('produce a diff that undoes the changes')),
-] + diffwsopts + [
-    ('U', 'unified', '',
-     _('number of lines of context to show'), _('NUM')),
-    ('', 'stat', None, _('output diffstat-style summary of changes')),
-    ('', 'root', '', _('produce diffs relative to subdirectory'), _('DIR')),
-]
+diffopts2 = (
+    [
+        ('', 'noprefix', None, _('omit a/ and b/ prefixes from filenames')),
+        (
+            'p',
+            'show-function',
+            None,
+            _('show which function each change is in'),
+        ),
+        ('', 'reverse', None, _('produce a diff that undoes the changes')),
+    ]
+    + diffwsopts
+    + [
+        ('U', 'unified', '', _('number of lines of context to show'), _('NUM')),
+        ('', 'stat', None, _('output diffstat-style summary of changes')),
+        ('', 'root', '', _('produce diffs relative to subdirectory'), _('DIR')),
+    ]
+)
 
 mergetoolopts = [
     ('t', 'tool', '', _('specify merge tool'), _('TOOL')),
 ]
 
 similarityopts = [
-    ('s', 'similarity', '',
-     _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
+    (
+        's',
+        'similarity',
+        '',
+        _('guess renamed files by similarity (0<=s<=100)'),
+        _('SIMILARITY'),
+    )
 ]
 
-subrepoopts = [
-    ('S', 'subrepos', None,
-     _('recurse into subrepositories'))
-]
+subrepoopts = [('S', 'subrepos', None, _('recurse into subrepositories'))]
 
 debugrevlogopts = [
     ('c', 'changelog', False, _('open changelog')),
@@ -182,6 +220,7 @@
 # editor text
 _linebelow = "^HG: ------------------------ >8 ------------------------$"
 
+
 def resolvecommitoptions(ui, opts):
     """modify commit options dict to handle related options
 
@@ -189,19 +228,23 @@
     the ``date`` option is set.
     """
     if opts.get('date') and opts.get('currentdate'):
-        raise error.Abort(_('--date and --currentdate are mutually '
-                            'exclusive'))
+        raise error.Abort(
+            _('--date and --currentdate are mutually ' 'exclusive')
+        )
     if opts.get(b'user') and opts.get(b'currentuser'):
-        raise error.Abort(_('--user and --currentuser are mutually '
-                            'exclusive'))
+        raise error.Abort(
+            _('--user and --currentuser are mutually ' 'exclusive')
+        )
 
     datemaydiffer = False  # date-only change should be ignored?
 
     if opts.get(b'currentdate'):
         opts[b'date'] = b'%d %d' % dateutil.makedate()
-    elif (not opts.get('date')
-          and ui.configbool('rewrite', 'update-timestamp')
-          and opts.get('currentdate') is None):
+    elif (
+        not opts.get('date')
+        and ui.configbool('rewrite', 'update-timestamp')
+        and opts.get('currentdate') is None
+    ):
         opts[b'date'] = b'%d %d' % dateutil.makedate()
         datemaydiffer = True
 
@@ -210,6 +253,7 @@
 
     return datemaydiffer
 
+
 def checknotesize(ui, opts):
     """ make sure note is of valid format """
 
@@ -222,24 +266,32 @@
     if b'\n' in note:
         raise error.Abort(_(b"note cannot contain a newline"))
 
+
 def ishunk(x):
     hunkclasses = (crecordmod.uihunk, patch.recordhunk)
     return isinstance(x, hunkclasses)
 
+
 def newandmodified(chunks, originalchunks):
     newlyaddedandmodifiedfiles = set()
     alsorestore = set()
     for chunk in chunks:
-        if (ishunk(chunk) and chunk.header.isnewfile() and chunk not in
-            originalchunks):
+        if (
+            ishunk(chunk)
+            and chunk.header.isnewfile()
+            and chunk not in originalchunks
+        ):
             newlyaddedandmodifiedfiles.add(chunk.header.filename())
-            alsorestore.update(set(chunk.header.files()) -
-                               {chunk.header.filename()})
+            alsorestore.update(
+                set(chunk.header.files()) - {chunk.header.filename()}
+            )
     return newlyaddedandmodifiedfiles, alsorestore
 
+
 def parsealiases(cmd):
     return cmd.split("|")
 
+
 def setupwrapcolorwrite(ui):
     # wrap ui.write so diff output can be labeled/colorized
     def wrapwrite(orig, *args, **kw):
@@ -248,29 +300,34 @@
             orig(chunk, label=label + l)
 
     oldwrite = ui.write
+
     def wrap(*args, **kwargs):
         return wrapwrite(oldwrite, *args, **kwargs)
+
     setattr(ui, 'write', wrap)
     return oldwrite
 
-def filterchunks(ui, originalhunks, usecurses, testfile, match,
-                 operation=None):
+
+def filterchunks(ui, originalhunks, usecurses, testfile, match, operation=None):
     try:
         if usecurses:
             if testfile:
                 recordfn = crecordmod.testdecorator(
-                    testfile, crecordmod.testchunkselector)
+                    testfile, crecordmod.testchunkselector
+                )
             else:
                 recordfn = crecordmod.chunkselector
 
-            return crecordmod.filterpatch(ui, originalhunks, recordfn,
-                                          operation)
+            return crecordmod.filterpatch(
+                ui, originalhunks, recordfn, operation
+            )
     except crecordmod.fallbackerror as e:
         ui.warn('%s\n' % e.message)
         ui.warn(_('falling back to text mode\n'))
 
     return patch.filterpatch(ui, originalhunks, match, operation)
 
+
 def recordfilter(ui, originalhunks, match, operation=None):
     """ Prompts the user to filter the originalhunks and return a list of
     selected hunks.
@@ -282,14 +339,17 @@
     testfile = ui.config('experimental', 'crecordtest')
     oldwrite = setupwrapcolorwrite(ui)
     try:
-        newchunks, newopts = filterchunks(ui, originalhunks, usecurses,
-                                          testfile, match, operation)
+        newchunks, newopts = filterchunks(
+            ui, originalhunks, usecurses, testfile, match, operation
+        )
     finally:
         ui.write = oldwrite
     return newchunks, newopts
 
-def dorecord(ui, repo, commitfunc, cmdsuggest, backupall,
-            filterfn, *pats, **opts):
+
+def dorecord(
+    ui, repo, commitfunc, cmdsuggest, backupall, filterfn, *pats, **opts
+):
     opts = pycompat.byteskwargs(opts)
     if not ui.interactive():
         if cmdsuggest:
@@ -300,7 +360,7 @@
 
     # make sure username is set before going interactive
     if not opts.get('user'):
-        ui.username() # raise exception, username not provided
+        ui.username()  # raise exception, username not provided
 
     def recordfunc(ui, repo, message, match, opts):
         """This is generic record driver.
@@ -321,8 +381,12 @@
         wctx = repo[None]
         merge = len(wctx.parents()) > 1
         if merge:
-            raise error.Abort(_('cannot partially commit a merge '
-                               '(use "hg commit" instead)'))
+            raise error.Abort(
+                _(
+                    'cannot partially commit a merge '
+                    '(use "hg commit" instead)'
+                )
+            )
 
         def fail(f, msg):
             raise error.Abort('%s: %s' % (f, msg))
@@ -339,17 +403,20 @@
 
         with repo.ui.configoverride(overrides, b'record'):
             # subrepoutil.precommit() modifies the status
-            tmpstatus = scmutil.status(copymod.copy(status[0]),
-                                       copymod.copy(status[1]),
-                                       copymod.copy(status[2]),
-                                       copymod.copy(status[3]),
-                                       copymod.copy(status[4]),
-                                       copymod.copy(status[5]),
-                                       copymod.copy(status[6]))
+            tmpstatus = scmutil.status(
+                copymod.copy(status[0]),
+                copymod.copy(status[1]),
+                copymod.copy(status[2]),
+                copymod.copy(status[3]),
+                copymod.copy(status[4]),
+                copymod.copy(status[5]),
+                copymod.copy(status[6]),
+            )
 
             # Force allows -X subrepo to skip the subrepo.
             subs, commitsubs, newstate = subrepoutil.precommit(
-                repo.ui, wctx, tmpstatus, match, force=True)
+                repo.ui, wctx, tmpstatus, match, force=True
+            )
             for s in subs:
                 if s in commitsubs:
                     dirtyreason = wctx.sub(s).dirtyreason(True)
@@ -357,9 +424,13 @@
 
         if not force:
             repo.checkcommitpatterns(wctx, vdirs, match, status, fail)
-        diffopts = patch.difffeatureopts(ui, opts=opts, whitespace=True,
-                                         section='commands',
-                                         configprefix='commit.interactive.')
+        diffopts = patch.difffeatureopts(
+            ui,
+            opts=opts,
+            whitespace=True,
+            section='commands',
+            configprefix='commit.interactive.',
+        )
         diffopts.nodates = True
         diffopts.git = True
         diffopts.showfunc = True
@@ -379,8 +450,9 @@
         # version without the edit in the workdir. We also will need to restore
         # files that were the sources of renames so that the patch application
         # works.
-        newlyaddedandmodifiedfiles, alsorestore = newandmodified(chunks,
-                                                                 originalchunks)
+        newlyaddedandmodifiedfiles, alsorestore = newandmodified(
+            chunks, originalchunks
+        )
         contenders = set()
         for h in chunks:
             try:
@@ -401,8 +473,11 @@
         if backupall:
             tobackup = changed
         else:
-            tobackup = [f for f in newfiles if f in modified or f in
-                        newlyaddedandmodifiedfiles]
+            tobackup = [
+                f
+                for f in newfiles
+                if f in modified or f in newlyaddedandmodifiedfiles
+            ]
         backups = {}
         if tobackup:
             backupdir = repo.vfs.join('record-backups')
@@ -414,8 +489,9 @@
         try:
             # backup continues
             for f in tobackup:
-                fd, tmpname = pycompat.mkstemp(prefix=f.replace('/', '_') + '.',
-                                               dir=backupdir)
+                fd, tmpname = pycompat.mkstemp(
+                    prefix=f.replace('/', '_') + '.', dir=backupdir
+                )
                 os.close(fd)
                 ui.debug('backup %r as %r\n' % (f, tmpname))
                 util.copyfile(repo.wjoin(f), tmpname, copystat=True)
@@ -431,12 +507,14 @@
 
             # 2.5 optionally review / modify patch in text editor
             if opts.get('review', False):
-                patchtext = (crecordmod.diffhelptext
-                             + crecordmod.patchhelptext
-                             + fp.read())
-                reviewedpatch = ui.edit(patchtext, "",
-                                        action="diff",
-                                        repopath=repo.path)
+                patchtext = (
+                    crecordmod.diffhelptext
+                    + crecordmod.patchhelptext
+                    + fp.read()
+                )
+                reviewedpatch = ui.edit(
+                    patchtext, "", action="diff", repopath=repo.path
+                )
                 fp.truncate(0)
                 fp.write(reviewedpatch)
                 fp.seek(0)
@@ -446,8 +524,13 @@
             if backups:
                 # Equivalent to hg.revert
                 m = scmutil.matchfiles(repo, set(backups.keys()) | alsorestore)
-                mergemod.update(repo, repo.dirstate.p1(), branchmerge=False,
-                                force=True, matcher=m)
+                mergemod.update(
+                    repo,
+                    repo.dirstate.p1(),
+                    branchmerge=False,
+                    force=True,
+                    matcher=m,
+                )
 
             # 3b. (apply)
             if dopatch:
@@ -497,6 +580,7 @@
 
     return commit(ui, repo, recordinwlock, pats, opts)
 
+
 class dirnode(object):
     """
     Represent a directory in user working copy with information required for
@@ -592,11 +676,12 @@
         for st, fpath in self.iterfilepaths():
             yield st, fpath
 
-        #recurse on the subdirs
+        # recurse on the subdirs
         for dirobj in self.subdirs.values():
             for st, fpath in dirobj.tersewalk(terseargs):
                 yield st, fpath
 
+
 def tersedir(statuslist, terseargs):
     """
     Terse the status if all the files in a directory shares the same status.
@@ -620,8 +705,15 @@
 
     # creating a dirnode object for the root of the repo
     rootobj = dirnode('')
-    pstatus = ('modified', 'added', 'deleted', 'clean', 'unknown',
-               'ignored', 'removed')
+    pstatus = (
+        'modified',
+        'added',
+        'deleted',
+        'clean',
+        'unknown',
+        'ignored',
+        'removed',
+    )
 
     tersedict = {}
     for attrname in pstatus:
@@ -646,12 +738,14 @@
 
     return tersedlist
 
+
 def _commentlines(raw):
     '''Surround lineswith a comment char and a new line'''
     lines = raw.splitlines()
     commentedlines = ['# %s' % line for line in lines]
     return '\n'.join(commentedlines) + '\n'
 
+
 def _conflictsmsg(repo):
     mergestate = mergemod.mergestate.read(repo)
     if not mergestate.active():
@@ -661,18 +755,27 @@
     unresolvedlist = [f for f in mergestate.unresolved() if m(f)]
     if unresolvedlist:
         mergeliststr = '\n'.join(
-            ['    %s' % util.pathto(repo.root, encoding.getcwd(), path)
-             for path in sorted(unresolvedlist)])
-        msg = _('''Unresolved merge conflicts:
+            [
+                '    %s' % util.pathto(repo.root, encoding.getcwd(), path)
+                for path in sorted(unresolvedlist)
+            ]
+        )
+        msg = (
+            _(
+                '''Unresolved merge conflicts:
 
 %s
 
-To mark files as resolved:  hg resolve --mark FILE''') % mergeliststr
+To mark files as resolved:  hg resolve --mark FILE'''
+            )
+            % mergeliststr
+        )
     else:
         msg = _('No unresolved merge conflicts.')
 
     return _commentlines(msg)
 
+
 def morestatus(repo, fm):
     statetuple = statemod.getrepostate(repo)
     label = 'status.morestatus'
@@ -686,6 +789,7 @@
         if helpfulmsg:
             fm.plain('%s\n' % _commentlines(helpfulmsg), label=label)
 
+
 def findpossible(cmd, table, strict=False):
     """
     Return cmd -> (aliases, command table entry)
@@ -724,6 +828,7 @@
 
     return choice, allcmds
 
+
 def findcmd(cmd, table, strict=True):
     """Return (aliases, command table entry) for command string."""
     choice, allcmds = findpossible(cmd, table, strict)
@@ -740,6 +845,7 @@
 
     raise error.UnknownCommand(cmd, allcmds)
 
+
 def changebranch(ui, repo, revs, label):
     """ Change the branch name of given revs to label """
 
@@ -770,6 +876,7 @@
         # avoid import cycle mercurial.cmdutil -> mercurial.context ->
         # mercurial.subrepo -> mercurial.cmdutil
         from . import context
+
         for rev in revs:
             ctx = repo[rev]
             oldbranch = ctx.branch()
@@ -783,8 +890,10 @@
                 except error.ManifestLookupError:
                     return None
 
-            ui.debug("changing branch of '%s' from '%s' to '%s'\n"
-                     % (hex(ctx.node()), oldbranch, label))
+            ui.debug(
+                "changing branch of '%s' from '%s' to '%s'\n"
+                % (hex(ctx.node()), oldbranch, label)
+            )
             extra = ctx.extra()
             extra['branch_change'] = hex(ctx.node())
             # While changing branch of set of linear commits, make sure that
@@ -797,14 +906,17 @@
             if p2 in replacements:
                 p2 = replacements[p2][0]
 
-            mc = context.memctx(repo, (p1, p2),
-                                ctx.description(),
-                                ctx.files(),
-                                filectxfn,
-                                user=ctx.user(),
-                                date=ctx.date(),
-                                extra=extra,
-                                branch=label)
+            mc = context.memctx(
+                repo,
+                (p1, p2),
+                ctx.description(),
+                ctx.files(),
+                filectxfn,
+                user=ctx.user(),
+                date=ctx.date(),
+                extra=extra,
+                branch=label,
+            )
 
             newnode = repo.commitctx(mc)
             replacements[ctx.node()] = (newnode,)
@@ -822,10 +934,12 @@
                 # avoid import cycle mercurial.cmdutil -> mercurial.hg ->
                 # mercurial.cmdutil
                 from . import hg
+
                 hg.update(repo, newid[0], quietempty=True)
 
         ui.status(_("changed branch on %d changesets\n") % len(replacements))
 
+
 def findrepo(p):
     while not os.path.isdir(os.path.join(p, ".hg")):
         oldp, p = p, os.path.dirname(p)
@@ -834,6 +948,7 @@
 
     return p
 
+
 def bailifchanged(repo, merge=True, hint=None):
     """ enforce the precondition that working directory must be clean.
 
@@ -852,14 +967,16 @@
     for s in sorted(ctx.substate):
         ctx.sub(s).bailifchanged(hint=hint)
 
+
 def logmessage(ui, opts):
     """ get the log message according to -m and -l option """
     message = opts.get('message')
     logfile = opts.get('logfile')
 
     if message and logfile:
-        raise error.Abort(_('options --message and --logfile are mutually '
-                           'exclusive'))
+        raise error.Abort(
+            _('options --message and --logfile are mutually ' 'exclusive')
+        )
     if not message and logfile:
         try:
             if isstdiofilename(logfile):
@@ -867,10 +984,13 @@
             else:
                 message = '\n'.join(util.readfile(logfile).splitlines())
         except IOError as inst:
-            raise error.Abort(_("can't read commit message '%s': %s") %
-                             (logfile, encoding.strtolocal(inst.strerror)))
+            raise error.Abort(
+                _("can't read commit message '%s': %s")
+                % (logfile, encoding.strtolocal(inst.strerror))
+            )
     return message
 
+
 def mergeeditform(ctxorbool, baseformname):
     """return appropriate editform name (referencing a committemplate)
 
@@ -888,8 +1008,10 @@
 
     return baseformname + ".normal"
 
-def getcommiteditor(edit=False, finishdesc=None, extramsg=None,
-                    editform='', **opts):
+
+def getcommiteditor(
+    edit=False, finishdesc=None, extramsg=None, editform='', **opts
+):
     """get appropriate commit message editor according to '--edit' option
 
     'finishdesc' is a function to be called with edited commit message
@@ -910,15 +1032,15 @@
     they are specific for usage in MQ.
     """
     if edit or finishdesc or extramsg:
-        return lambda r, c, s: commitforceeditor(r, c, s,
-                                                 finishdesc=finishdesc,
-                                                 extramsg=extramsg,
-                                                 editform=editform)
+        return lambda r, c, s: commitforceeditor(
+            r, c, s, finishdesc=finishdesc, extramsg=extramsg, editform=editform
+        )
     elif editform:
         return lambda r, c, s: commiteditor(r, c, s, editform=editform)
     else:
         return commiteditor
 
+
 def _escapecommandtemplate(tmpl):
     parts = []
     for typ, start, end in templater.scantemplate(tmpl, raw=True):
@@ -928,6 +1050,7 @@
             parts.append(tmpl[start:end])
     return b''.join(parts)
 
+
 def rendercommandtemplate(ui, tmpl, props):
     r"""Expand a literal template 'tmpl' in a way suitable for command line
 
@@ -946,6 +1069,7 @@
     t = formatter.maketemplater(ui, _escapecommandtemplate(tmpl))
     return t.renderdefault(props)
 
+
 def rendertemplate(ctx, tmpl, props=None):
     """Expand a literal template 'tmpl' byte-string against one changeset
 
@@ -954,13 +1078,15 @@
     """
     repo = ctx.repo()
     tres = formatter.templateresources(repo.ui, repo)
-    t = formatter.maketemplater(repo.ui, tmpl, defaults=templatekw.keywords,
-                                resources=tres)
+    t = formatter.maketemplater(
+        repo.ui, tmpl, defaults=templatekw.keywords, resources=tres
+    )
     mapping = {'ctx': ctx}
     if props:
         mapping.update(props)
     return t.renderdefault(mapping)
 
+
 def _buildfntemplate(pat, total=None, seqno=None, revwidth=None, pathname=None):
     r"""Convert old-style filename format string to template string
 
@@ -1018,17 +1144,20 @@
                 break
             newname.append(stringutil.escapestr(pat[i:n]))
             if n + 2 > end:
-                raise error.Abort(_("incomplete format spec in output "
-                                    "filename"))
-            c = pat[n + 1:n + 2]
+                raise error.Abort(
+                    _("incomplete format spec in output " "filename")
+                )
+            c = pat[n + 1 : n + 2]
             i = n + 2
             try:
                 newname.append(expander[c])
             except KeyError:
-                raise error.Abort(_("invalid format spec '%%%s' in output "
-                                    "filename") % c)
+                raise error.Abort(
+                    _("invalid format spec '%%%s' in output " "filename") % c
+                )
     return ''.join(newname)
 
+
 def makefilename(ctx, pat, **props):
     if not pat:
         return pat
@@ -1038,10 +1167,12 @@
     # disable the expansion.
     return rendertemplate(ctx, tmpl, pycompat.byteskwargs(props))
 
+
 def isstdiofilename(pat):
     """True if the given pat looks like a filename denoting stdin/stdout"""
     return not pat or pat == '-'
 
+
 class _unclosablefile(object):
     def __init__(self, fp):
         self._fp = fp
@@ -1061,6 +1192,7 @@
     def __exit__(self, exc_type, exc_value, exc_tb):
         pass
 
+
 def makefileobj(ctx, pat, mode='wb', **props):
     writable = mode not in ('r', 'rb')
 
@@ -1074,6 +1206,7 @@
     fn = makefilename(ctx, pat, **props)
     return open(fn, mode)
 
+
 def openstorage(repo, cmd, file_, opts, returnrevlog=False):
     """opens the changelog, manifest, a filelog or a given revlog"""
     cl = opts['changelog']
@@ -1088,8 +1221,10 @@
         if file_:
             msg = _('cannot specify filename with --changelog or --manifest')
         elif not repo:
-            msg = _('cannot specify --changelog or --manifest or --dir '
-                    'without a repository')
+            msg = _(
+                'cannot specify --changelog or --manifest or --dir '
+                'without a repository'
+            )
     if msg:
         raise error.Abort(msg)
 
@@ -1099,8 +1234,12 @@
             r = repo.unfiltered().changelog
         elif dir:
             if 'treemanifest' not in repo.requirements:
-                raise error.Abort(_("--dir can only be used on repos with "
-                                   "treemanifest enabled"))
+                raise error.Abort(
+                    _(
+                        "--dir can only be used on repos with "
+                        "treemanifest enabled"
+                    )
+                )
             if not dir.endswith('/'):
                 dir = dir + '/'
             dirlog = repo.manifestlog.getstorage(dir)
@@ -1131,10 +1270,12 @@
             raise error.CommandError(cmd, _('invalid arguments'))
         if not os.path.isfile(file_):
             raise error.Abort(_("revlog '%s' not found") % file_)
-        r = revlog.revlog(vfsmod.vfs(encoding.getcwd(), audit=False),
-                          file_[:-2] + ".i")
+        r = revlog.revlog(
+            vfsmod.vfs(encoding.getcwd(), audit=False), file_[:-2] + ".i"
+        )
     return r
 
+
 def openrevlog(repo, cmd, file_, opts):
     """Obtain a revlog backing storage of an item.
 
@@ -1147,6 +1288,7 @@
     """
     return openstorage(repo, cmd, file_, opts, returnrevlog=True)
 
+
 def copy(ui, repo, pats, opts, rename=False):
     # called with the repo lock held
     #
@@ -1159,6 +1301,7 @@
     wctx = repo[None]
 
     uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
+
     def walkpat(pat):
         srcs = []
         if after:
@@ -1174,8 +1317,13 @@
                 if exact and state == '?':
                     ui.warn(_('%s: not copying - file is not managed\n') % rel)
                 if exact and state == 'r':
-                    ui.warn(_('%s: not copying - file has been marked for'
-                              ' remove\n') % rel)
+                    ui.warn(
+                        _(
+                            '%s: not copying - file has been marked for'
+                            ' remove\n'
+                        )
+                        % rel
+                    )
                 continue
             # abs: hgsep
             # rel: ossep
@@ -1202,20 +1350,26 @@
         # check for collisions
         prevsrc = targets.get(abstarget)
         if prevsrc is not None:
-            ui.warn(_('%s: not overwriting - %s collides with %s\n') %
-                    (reltarget, repo.pathto(abssrc, cwd),
-                     repo.pathto(prevsrc, cwd)))
-            return True # report a failure
+            ui.warn(
+                _('%s: not overwriting - %s collides with %s\n')
+                % (
+                    reltarget,
+                    repo.pathto(abssrc, cwd),
+                    repo.pathto(prevsrc, cwd),
+                )
+            )
+            return True  # report a failure
 
         # check for overwrites
         exists = os.path.lexists(target)
         samefile = False
         if exists and abssrc != abstarget:
-            if (repo.dirstate.normalize(abssrc) ==
-                repo.dirstate.normalize(abstarget)):
+            if repo.dirstate.normalize(abssrc) == repo.dirstate.normalize(
+                abstarget
+            ):
                 if not rename:
                     ui.warn(_("%s: can't copy - same file\n") % reltarget)
-                    return True # report a failure
+                    return True  # report a failure
                 exists = False
                 samefile = True
 
@@ -1228,11 +1382,21 @@
                     else:
                         flags = '--force'
                     if rename:
-                        hint = _("('hg rename %s' to replace the file by "
-                                 'recording a rename)\n') % flags
+                        hint = (
+                            _(
+                                "('hg rename %s' to replace the file by "
+                                'recording a rename)\n'
+                            )
+                            % flags
+                        )
                     else:
-                        hint = _("('hg copy %s' to replace the file by "
-                                 'recording a copy)\n') % flags
+                        hint = (
+                            _(
+                                "('hg copy %s' to replace the file by "
+                                'recording a copy)\n'
+                            )
+                            % flags
+                        )
                 else:
                     msg = _('%s: not overwriting - file exists\n')
                     if rename:
@@ -1241,17 +1405,21 @@
                         hint = _("('hg copy --after' to record the copy)\n")
                 ui.warn(msg % reltarget)
                 ui.warn(hint)
-                return True # report a failure
+                return True  # report a failure
 
         if after:
             if not exists:
                 if rename:
-                    ui.warn(_('%s: not recording move - %s does not exist\n') %
-                            (relsrc, reltarget))
+                    ui.warn(
+                        _('%s: not recording move - %s does not exist\n')
+                        % (relsrc, reltarget)
+                    )
                 else:
-                    ui.warn(_('%s: not recording copy - %s does not exist\n') %
-                            (relsrc, reltarget))
-                return True # report a failure
+                    ui.warn(
+                        _('%s: not recording copy - %s does not exist\n')
+                        % (relsrc, reltarget)
+                    )
+                return True  # report a failure
         elif not dryrun:
             try:
                 if exists:
@@ -1273,9 +1441,11 @@
                     ui.warn(_('%s: deleted in working directory\n') % relsrc)
                     srcexists = False
                 else:
-                    ui.warn(_('%s: cannot copy - %s\n') %
-                            (relsrc, encoding.strtolocal(inst.strerror)))
-                    return True # report a failure
+                    ui.warn(
+                        _('%s: cannot copy - %s\n')
+                        % (relsrc, encoding.strtolocal(inst.strerror))
+                    )
+                    return True  # report a failure
 
         if ui.verbose or not exact:
             if rename:
@@ -1286,8 +1456,9 @@
         targets[abstarget] = abssrc
 
         # fix up dirstate
-        scmutil.dirstatecopy(ui, repo, wctx, abssrc, abstarget,
-                             dryrun=dryrun, cwd=cwd)
+        scmutil.dirstatecopy(
+            ui, repo, wctx, abssrc, abstarget, dryrun=dryrun, cwd=cwd
+        )
         if rename and not dryrun:
             if not after and srcexists and not samefile:
                 rmdir = repo.ui.configbool('experimental', 'removeemptydirs')
@@ -1310,8 +1481,9 @@
                 striplen += len(pycompat.ossep)
             res = lambda p: os.path.join(dest, util.localpath(p)[striplen:])
         elif destdirexists:
-            res = lambda p: os.path.join(dest,
-                                         os.path.basename(util.localpath(p)))
+            res = lambda p: os.path.join(
+                dest, os.path.basename(util.localpath(p))
+            )
         else:
             res = lambda p: dest
         return res
@@ -1323,8 +1495,9 @@
     def targetpathafterfn(pat, dest, srcs):
         if matchmod.patkind(pat):
             # a mercurial pattern
-            res = lambda p: os.path.join(dest,
-                                         os.path.basename(util.localpath(p)))
+            res = lambda p: os.path.join(
+                dest, os.path.basename(util.localpath(p))
+            )
         else:
             abspfx = pathutil.canonpath(repo.root, cwd, pat)
             if len(abspfx) < len(srcs[0][0]):
@@ -1349,13 +1522,13 @@
                         striplen1 += len(pycompat.ossep)
                     if evalpath(striplen1) > score:
                         striplen = striplen1
-                res = lambda p: os.path.join(dest,
-                                             util.localpath(p)[striplen:])
+                res = lambda p: os.path.join(dest, util.localpath(p)[striplen:])
             else:
                 # a file
                 if destdirexists:
-                    res = lambda p: os.path.join(dest,
-                                        os.path.basename(util.localpath(p)))
+                    res = lambda p: os.path.join(
+                        dest, os.path.basename(util.localpath(p))
+                    )
                 else:
                     res = lambda p: dest
         return res
@@ -1369,8 +1542,12 @@
     destdirexists = os.path.isdir(dest) and not os.path.islink(dest)
     if not destdirexists:
         if len(pats) > 1 or matchmod.patkind(pats[0]):
-            raise error.Abort(_('with multiple sources, destination must be an '
-                               'existing directory'))
+            raise error.Abort(
+                _(
+                    'with multiple sources, destination must be an '
+                    'existing directory'
+                )
+            )
         if util.endswithsep(dest):
             raise error.Abort(_('destination %s is not a directory') % dest)
 
@@ -1394,10 +1571,11 @@
 
     return errors != 0
 
+
 ## facility to let extension process additional data into an import patch
 # list of identifier to be executed in order
 extrapreimport = []  # run before commit
-extrapostimport = [] # run after commit
+extrapostimport = []  # run after commit
 # mapping from identifier to actual import function
 #
 # 'preimport' are run before the commit is made and are provided the following
@@ -1415,6 +1593,7 @@
 # - ctx: the changectx created by import.
 extrapostimportmap = {}
 
+
 def tryimportone(ui, repo, patchdata, parents, opts, msgs, updatefunc):
     """Utility function used by commands.import to import a single patch
 
@@ -1489,8 +1668,12 @@
         except error.RepoError:
             p1, p2 = parents
         if p2.node() == nullid:
-            ui.warn(_("warning: import the patch as a normal revision\n"
-                      "(use --exact to import the patch as a merge)\n"))
+            ui.warn(
+                _(
+                    "warning: import the patch as a normal revision\n"
+                    "(use --exact to import the patch as a merge)\n"
+                )
+            )
     else:
         p1, p2 = parents
 
@@ -1507,8 +1690,16 @@
         partial = opts.get('partial', False)
         files = set()
         try:
-            patch.patch(ui, repo, tmpname, strip=strip, prefix=prefix,
-                        files=files, eolmode=None, similarity=sim / 100.0)
+            patch.patch(
+                ui,
+                repo,
+                tmpname,
+                strip=strip,
+                prefix=prefix,
+                files=files,
+                eolmode=None,
+                similarity=sim / 100.0,
+            )
         except error.PatchError as e:
             if not partial:
                 raise error.Abort(pycompat.bytestr(e))
@@ -1531,8 +1722,9 @@
             if opts.get('exact'):
                 editor = None
             else:
-                editor = getcommiteditor(editform=editform,
-                                         **pycompat.strkwargs(opts))
+                editor = getcommiteditor(
+                    editform=editform, **pycompat.strkwargs(opts)
+                )
             extra = {}
             for idfunc in extrapreimport:
                 extrapreimportmap[idfunc](repo, patchdata, extra, opts)
@@ -1540,9 +1732,9 @@
             if partial:
                 overrides[('ui', 'allowemptycommit')] = True
             with repo.ui.configoverride(overrides, 'import'):
-                n = repo.commit(message, user,
-                                date, match=m,
-                                editor=editor, extra=extra)
+                n = repo.commit(
+                    message, user, date, match=m, editor=editor, extra=extra
+                )
                 for idfunc in extrapostimport:
                     extrapostimportmap[idfunc](repo[n])
     else:
@@ -1554,22 +1746,34 @@
         try:
             files = set()
             try:
-                patch.patchrepo(ui, repo, p1, store, tmpname, strip, prefix,
-                                files, eolmode=None)
+                patch.patchrepo(
+                    ui,
+                    repo,
+                    p1,
+                    store,
+                    tmpname,
+                    strip,
+                    prefix,
+                    files,
+                    eolmode=None,
+                )
             except error.PatchError as e:
                 raise error.Abort(stringutil.forcebytestr(e))
             if opts.get('exact'):
                 editor = None
             else:
                 editor = getcommiteditor(editform='import.bypass')
-            memctx = context.memctx(repo, (p1.node(), p2.node()),
-                                    message,
-                                    files=files,
-                                    filectxfn=store,
-                                    user=user,
-                                    date=date,
-                                    branch=branch,
-                                    editor=editor)
+            memctx = context.memctx(
+                repo,
+                (p1.node(), p2.node()),
+                message,
+                files=files,
+                filectxfn=store,
+                user=user,
+                date=date,
+                branch=branch,
+                editor=editor,
+            )
             n = memctx.commit()
         finally:
             store.close()
@@ -1585,6 +1789,7 @@
         msg = _('created %s') % short(n)
     return msg, n, rejects
 
+
 # facility to let extensions include additional data in an exported patch
 # list of identifiers to be executed in order
 extraexport = []
@@ -1593,6 +1798,7 @@
 # it is given two arguments (sequencenumber, changectx)
 extraexportmap = {}
 
+
 def _exportsingle(repo, ctx, fm, match, switch_parent, seqno, diffopts):
     node = scmutil.binnode(ctx)
     parents = [p.node() for p in ctx.parents() if p]
@@ -1610,8 +1816,9 @@
     fm.write('user', '# User %s\n', ctx.user())
     fm.plain('# Date %d %d\n' % ctx.date())
     fm.write('date', '#      %s\n', fm.formatdate(ctx.date()))
-    fm.condwrite(branch and branch != 'default',
-                 'branch', '# Branch %s\n', branch)
+    fm.condwrite(
+        branch and branch != 'default', 'branch', '# Branch %s\n', branch
+    )
     fm.write('node', '# Node ID %s\n', hex(node))
     fm.plain('# Parent  %s\n' % hex(prev))
     if len(parents) > 1:
@@ -1636,6 +1843,7 @@
         # TODO: make it structured?
         fm.data(diff=b''.join(chunkiter))
 
+
 def _exportfile(repo, revs, fm, dest, switch_parent, diffopts, match):
     """Export changesets to stdout or a single file"""
     for seqno, rev in enumerate(revs, 1):
@@ -1645,8 +1853,10 @@
         fm.startitem()
         _exportsingle(repo, ctx, fm, match, switch_parent, seqno, diffopts)
 
-def _exportfntemplate(repo, revs, basefm, fntemplate, switch_parent, diffopts,
-                      match):
+
+def _exportfntemplate(
+    repo, revs, basefm, fntemplate, switch_parent, diffopts, match
+):
     """Export changesets to possibly multiple files"""
     total = len(revs)
     revwidth = max(len(str(rev)) for rev in revs)
@@ -1654,8 +1864,9 @@
 
     for seqno, rev in enumerate(revs, 1):
         ctx = repo[rev]
-        dest = makefilename(ctx, fntemplate,
-                            total=total, seqno=seqno, revwidth=revwidth)
+        dest = makefilename(
+            ctx, fntemplate, total=total, seqno=seqno, revwidth=revwidth
+        )
         filemap.setdefault(dest, []).append((seqno, rev))
 
     for dest in filemap:
@@ -1664,8 +1875,10 @@
             for seqno, rev in filemap[dest]:
                 fm.startitem()
                 ctx = repo[rev]
-                _exportsingle(repo, ctx, fm, match, switch_parent, seqno,
-                              diffopts)
+                _exportsingle(
+                    repo, ctx, fm, match, switch_parent, seqno, diffopts
+                )
+
 
 def _prefetchchangedfiles(repo, revs, match):
     allfiles = set()
@@ -1675,8 +1888,16 @@
                 allfiles.add(file)
     scmutil.prefetchfiles(repo, revs, scmutil.matchfiles(repo, allfiles))
 
-def export(repo, revs, basefm, fntemplate='hg-%h.patch', switch_parent=False,
-           opts=None, match=None):
+
+def export(
+    repo,
+    revs,
+    basefm,
+    fntemplate='hg-%h.patch',
+    switch_parent=False,
+    opts=None,
+    match=None,
+):
     '''export changesets as hg patches
 
     Args:
@@ -1704,8 +1925,10 @@
     if not fntemplate:
         _exportfile(repo, revs, basefm, '<unnamed>', switch_parent, opts, match)
     else:
-        _exportfntemplate(repo, revs, basefm, fntemplate, switch_parent, opts,
-                          match)
+        _exportfntemplate(
+            repo, revs, basefm, fntemplate, switch_parent, opts, match
+        )
+
 
 def exportfile(repo, revs, fp, switch_parent=False, opts=None, match=None):
     """Export changesets to the given file stream"""
@@ -1715,6 +1938,7 @@
     with formatter.formatter(repo.ui, fp, 'export', {}) as fm:
         _exportfile(repo, revs, fm, dest, switch_parent, opts, match)
 
+
 def showmarker(fm, marker, index=None):
     """utility function to display obsolescence marker in a readable way
 
@@ -1723,13 +1947,17 @@
         fm.write('index', '%i ', index)
     fm.write('prednode', '%s ', hex(marker.prednode()))
     succs = marker.succnodes()
-    fm.condwrite(succs, 'succnodes', '%s ',
-                 fm.formatlist(map(hex, succs), name='node'))
+    fm.condwrite(
+        succs, 'succnodes', '%s ', fm.formatlist(map(hex, succs), name='node')
+    )
     fm.write('flag', '%X ', marker.flags())
     parents = marker.parentnodes()
     if parents is not None:
-        fm.write('parentnodes', '{%s} ',
-                 fm.formatlist(map(hex, parents), name='node', sep=', '))
+        fm.write(
+            'parentnodes',
+            '{%s} ',
+            fm.formatlist(map(hex, parents), name='node', sep=', '),
+        )
     fm.write('date', '(%s) ', fm.formatdate(marker.date()))
     meta = marker.metadata().copy()
     meta.pop('date', None)
@@ -1737,6 +1965,7 @@
     fm.write('metadata', '{%s}', fm.formatdict(smeta, fmt='%r: %r', sep=', '))
     fm.plain('\n')
 
+
 def finddate(ui, repo, date):
     """Find the tipmost changeset that matches the given date spec"""
 
@@ -1752,18 +1981,22 @@
     for ctx in walkchangerevs(repo, m, {'rev': None}, prep):
         rev = ctx.rev()
         if rev in results:
-            ui.status(_("found revision %s from %s\n") %
-                      (rev, dateutil.datestr(results[rev])))
+            ui.status(
+                _("found revision %s from %s\n")
+                % (rev, dateutil.datestr(results[rev]))
+            )
             return '%d' % rev
 
     raise error.Abort(_("revision matching date not found"))
 
+
 def increasingwindows(windowsize=8, sizelimit=512):
     while True:
         yield windowsize
         if windowsize < sizelimit:
             windowsize *= 2
 
+
 def _walkrevs(repo, opts):
     # Default --rev value depends on --follow but --follow behavior
     # depends on revisions resolved from --rev...
@@ -1779,9 +2012,11 @@
         revs.reverse()
     return revs
 
+
 class FileWalkError(Exception):
     pass
 
+
 def walkfilerevs(repo, match, follow, revs, fncache):
     '''Walks the file history for the matched files.
 
@@ -1793,6 +2028,7 @@
     wanted = set()
     copies = []
     minrev, maxrev = min(revs), max(revs)
+
     def filerevs(filelog, last):
         """
         Only files, no patterns.  Check the history of each file.
@@ -1817,17 +2053,21 @@
                 if p != nullrev:
                     parentlinkrevs.append(filelog.linkrev(p))
             n = filelog.node(j)
-            revs.append((linkrev, parentlinkrevs,
-                         follow and filelog.renamed(n)))
+            revs.append(
+                (linkrev, parentlinkrevs, follow and filelog.renamed(n))
+            )
 
         return reversed(revs)
+
     def iterfiles():
         pctx = repo['.']
         for filename in match.files():
             if follow:
                 if filename not in pctx:
-                    raise error.Abort(_('cannot follow file not in parent '
-                                       'revision: "%s"') % filename)
+                    raise error.Abort(
+                        _('cannot follow file not in parent ' 'revision: "%s"')
+                        % filename
+                    )
                 yield filename, pctx[filename].filenode()
             else:
                 yield filename, None
@@ -1842,7 +2082,8 @@
                 # try to find matching entries on the slow path.
                 if follow:
                     raise error.Abort(
-                        _('cannot follow nonexistent file: "%s"') % file_)
+                        _('cannot follow nonexistent file: "%s"') % file_
+                    )
                 raise FileWalkError("Cannot walk via filelog")
             else:
                 continue
@@ -1879,6 +2120,7 @@
 
     return wanted
 
+
 class _followfilter(object):
     def __init__(self, repo, onlyfirst=False):
         self.repo = repo
@@ -1891,8 +2133,9 @@
             if self.onlyfirst:
                 return self.repo.changelog.parentrevs(rev)[0:1]
             else:
-                return filter(lambda x: x != nullrev,
-                              self.repo.changelog.parentrevs(rev))
+                return filter(
+                    lambda x: x != nullrev, self.repo.changelog.parentrevs(rev)
+                )
 
         if self.startrev == nullrev:
             self.startrev = rev
@@ -1917,6 +2160,7 @@
 
         return False
 
+
 def walkchangerevs(repo, match, opts, prepare):
     '''Iterate over files and the revs in which they changed.
 
@@ -1972,8 +2216,9 @@
         # changed files
 
         if follow:
-            raise error.Abort(_('can only follow copies/renames for explicit '
-                               'filenames'))
+            raise error.Abort(
+                _('can only follow copies/renames for explicit ' 'filenames')
+            )
 
         # The slow path checks files modified in every changeset.
         # This is really slow on large repos, so compute the set lazily.
@@ -2023,9 +2268,12 @@
     def iterate():
         if follow and match.always():
             ff = _followfilter(repo, onlyfirst=opts.get('follow_first'))
+
             def want(rev):
                 return ff.match(rev) and rev in wanted
+
         else:
+
             def want(rev):
                 return rev in wanted
 
@@ -2044,6 +2292,7 @@
                 fns = fncache.get(rev)
                 ctx = change(rev)
                 if not fns:
+
                     def fns_generator():
                         if allfiles:
                             fiter = iter(ctx)
@@ -2052,6 +2301,7 @@
                         for f in fiter:
                             if match(f):
                                 yield f
+
                     fns = fns_generator()
                 prepare(ctx, fns)
             for rev in nrevs:
@@ -2062,6 +2312,7 @@
 
     return iterate()
 
+
 def add(ui, repo, match, prefix, uipathfn, explicitonly, **opts):
     bad = []
 
@@ -2078,16 +2329,24 @@
     dirstate = repo.dirstate
     # We don't want to just call wctx.walk here, since it would return a lot of
     # clean files, which we aren't interested in and takes time.
-    for f in sorted(dirstate.walk(badmatch, subrepos=sorted(wctx.substate),
-                                  unknown=True, ignored=False, full=False)):
+    for f in sorted(
+        dirstate.walk(
+            badmatch,
+            subrepos=sorted(wctx.substate),
+            unknown=True,
+            ignored=False,
+            full=False,
+        )
+    ):
         exact = match.exact(f)
         if exact or not explicitonly and f not in wctx and repo.wvfs.lexists(f):
             if cca:
                 cca(f)
             names.append(f)
             if ui.verbose or not exact:
-                ui.status(_('adding %s\n') % uipathfn(f),
-                          label='ui.addremove.added')
+                ui.status(
+                    _('adding %s\n') % uipathfn(f), label='ui.addremove.added'
+                )
 
     for subpath in sorted(wctx.substate):
         sub = wctx.sub(subpath)
@@ -2096,20 +2355,24 @@
             subprefix = repo.wvfs.reljoin(prefix, subpath)
             subuipathfn = scmutil.subdiruipathfn(subpath, uipathfn)
             if opts.get(r'subrepos'):
-                bad.extend(sub.add(ui, submatch, subprefix, subuipathfn, False,
-                                   **opts))
+                bad.extend(
+                    sub.add(ui, submatch, subprefix, subuipathfn, False, **opts)
+                )
             else:
-                bad.extend(sub.add(ui, submatch, subprefix, subuipathfn, True,
-                                   **opts))
+                bad.extend(
+                    sub.add(ui, submatch, subprefix, subuipathfn, True, **opts)
+                )
         except error.LookupError:
-            ui.status(_("skipping missing subrepository: %s\n")
-                           % uipathfn(subpath))
+            ui.status(
+                _("skipping missing subrepository: %s\n") % uipathfn(subpath)
+            )
 
     if not opts.get(r'dry_run'):
         rejected = wctx.add(names, prefix)
         bad.extend(f for f in rejected if f in match.files())
     return bad
 
+
 def addwebdirpath(repo, serverpath, webconf):
     webconf[serverpath] = repo.root
     repo.ui.debug('adding %s = %s\n' % (serverpath, repo.root))
@@ -2119,8 +2382,10 @@
         for subpath in ctx.substate:
             ctx.sub(subpath).addwebdirpath(serverpath, webconf)
 
-def forget(ui, repo, match, prefix, uipathfn, explicitonly, dryrun,
-           interactive):
+
+def forget(
+    ui, repo, match, prefix, uipathfn, explicitonly, dryrun, interactive
+):
     if dryrun and interactive:
         raise error.Abort(_("cannot specify both --dry-run and --interactive"))
     bad = []
@@ -2139,14 +2404,19 @@
         subprefix = repo.wvfs.reljoin(prefix, subpath)
         subuipathfn = scmutil.subdiruipathfn(subpath, uipathfn)
         try:
-            subbad, subforgot = sub.forget(submatch, subprefix, subuipathfn,
-                                           dryrun=dryrun,
-                                           interactive=interactive)
+            subbad, subforgot = sub.forget(
+                submatch,
+                subprefix,
+                subuipathfn,
+                dryrun=dryrun,
+                interactive=interactive,
+            )
             bad.extend([subpath + '/' + f for f in subbad])
             forgot.extend([subpath + '/' + f for f in subforgot])
         except error.LookupError:
-            ui.status(_("skipping missing subrepository: %s\n")
-                           % uipathfn(subpath))
+            ui.status(
+                _("skipping missing subrepository: %s\n") % uipathfn(subpath)
+            )
 
     if not explicitonly:
         for f in match.files():
@@ -2159,42 +2429,48 @@
                         # purely from data cached by the status walk above.
                         if repo.dirstate.normalize(f) in repo.dirstate:
                             continue
-                        ui.warn(_('not removing %s: '
-                                  'file is already untracked\n')
-                                % uipathfn(f))
+                        ui.warn(
+                            _('not removing %s: ' 'file is already untracked\n')
+                            % uipathfn(f)
+                        )
                     bad.append(f)
 
     if interactive:
-        responses = _('[Ynsa?]'
-                      '$$ &Yes, forget this file'
-                      '$$ &No, skip this file'
-                      '$$ &Skip remaining files'
-                      '$$ Include &all remaining files'
-                      '$$ &? (display help)')
+        responses = _(
+            '[Ynsa?]'
+            '$$ &Yes, forget this file'
+            '$$ &No, skip this file'
+            '$$ &Skip remaining files'
+            '$$ Include &all remaining files'
+            '$$ &? (display help)'
+        )
         for filename in forget[:]:
-            r = ui.promptchoice(_('forget %s %s') %
-                                (uipathfn(filename), responses))
-            if r == 4: # ?
+            r = ui.promptchoice(
+                _('forget %s %s') % (uipathfn(filename), responses)
+            )
+            if r == 4:  # ?
                 while r == 4:
                     for c, t in ui.extractchoices(responses)[1]:
                         ui.write('%s - %s\n' % (c, encoding.lower(t)))
-                    r = ui.promptchoice(_('forget %s %s') %
-                                        (uipathfn(filename), responses))
-            if r == 0: # yes
+                    r = ui.promptchoice(
+                        _('forget %s %s') % (uipathfn(filename), responses)
+                    )
+            if r == 0:  # yes
                 continue
-            elif r == 1: # no
+            elif r == 1:  # no
                 forget.remove(filename)
-            elif r == 2: # Skip
+            elif r == 2:  # Skip
                 fnindex = forget.index(filename)
                 del forget[fnindex:]
                 break
-            elif r == 3: # All
+            elif r == 3:  # All
                 break
 
     for f in forget:
         if ui.verbose or not match.exact(f) or interactive:
-            ui.status(_('removing %s\n') % uipathfn(f),
-                      label='ui.addremove.removed')
+            ui.status(
+                _('removing %s\n') % uipathfn(f), label='ui.addremove.removed'
+            )
 
     if not dryrun:
         rejected = wctx.forget(forget, prefix)
@@ -2202,6 +2478,7 @@
         forgot.extend(f for f in forget if f not in rejected)
     return bad, forgot
 
+
 def files(ui, ctx, m, uipathfn, fm, fmt, subrepos):
     ret = 1
 
@@ -2219,21 +2496,27 @@
     for subpath in sorted(ctx.substate):
         submatch = matchmod.subdirmatcher(subpath, m)
         subuipathfn = scmutil.subdiruipathfn(subpath, uipathfn)
-        if (subrepos or m.exact(subpath) or any(submatch.files())):
+        if subrepos or m.exact(subpath) or any(submatch.files()):
             sub = ctx.sub(subpath)
             try:
                 recurse = m.exact(subpath) or subrepos
-                if sub.printfiles(ui, submatch, subuipathfn, fm, fmt,
-                                  recurse) == 0:
+                if (
+                    sub.printfiles(ui, submatch, subuipathfn, fm, fmt, recurse)
+                    == 0
+                ):
                     ret = 0
             except error.LookupError:
-                ui.status(_("skipping missing subrepository: %s\n")
-                               % uipathfn(subpath))
+                ui.status(
+                    _("skipping missing subrepository: %s\n")
+                    % uipathfn(subpath)
+                )
 
     return ret
 
-def remove(ui, repo, m, prefix, uipathfn, after, force, subrepos, dryrun,
-           warnings=None):
+
+def remove(
+    ui, repo, m, prefix, uipathfn, after, force, subrepos, dryrun, warnings=None
+):
     ret = 0
     s = repo.status(match=m, clean=True)
     modified, added, deleted, clean = s[0], s[1], s[3], s[6]
@@ -2247,8 +2530,9 @@
         warn = False
 
     subs = sorted(wctx.substate)
-    progress = ui.makeprogress(_('searching'), total=len(subs),
-                               unit=_('subrepos'))
+    progress = ui.makeprogress(
+        _('searching'), total=len(subs), unit=_('subrepos')
+    )
     for subpath in subs:
         submatch = matchmod.subdirmatcher(subpath, m)
         subprefix = repo.wvfs.reljoin(prefix, subpath)
@@ -2257,20 +2541,30 @@
             progress.increment()
             sub = wctx.sub(subpath)
             try:
-                if sub.removefiles(submatch, subprefix, subuipathfn, after,
-                                   force, subrepos, dryrun, warnings):
+                if sub.removefiles(
+                    submatch,
+                    subprefix,
+                    subuipathfn,
+                    after,
+                    force,
+                    subrepos,
+                    dryrun,
+                    warnings,
+                ):
                     ret = 1
             except error.LookupError:
-                warnings.append(_("skipping missing subrepository: %s\n")
-                               % uipathfn(subpath))
+                warnings.append(
+                    _("skipping missing subrepository: %s\n")
+                    % uipathfn(subpath)
+                )
     progress.complete()
 
     # warn about failure to delete explicit files/dirs
     deleteddirs = util.dirs(deleted)
     files = m.files()
-    progress = ui.makeprogress(_('deleting'), total=len(files),
-                               unit=_('files'))
+    progress = ui.makeprogress(_('deleting'), total=len(files), unit=_('files'))
     for f in files:
+
         def insubrepo():
             for subpath in wctx.substate:
                 if f.startswith(subpath + '/'):
@@ -2279,17 +2573,18 @@
 
         progress.increment()
         isdir = f in deleteddirs or wctx.hasdir(f)
-        if (f in repo.dirstate or isdir or f == '.'
-            or insubrepo() or f in subs):
+        if f in repo.dirstate or isdir or f == '.' or insubrepo() or f in subs:
             continue
 
         if repo.wvfs.exists(f):
             if repo.wvfs.isdir(f):
-                warnings.append(_('not removing %s: no tracked files\n')
-                        % uipathfn(f))
+                warnings.append(
+                    _('not removing %s: no tracked files\n') % uipathfn(f)
+                )
             else:
-                warnings.append(_('not removing %s: file is untracked\n')
-                        % uipathfn(f))
+                warnings.append(
+                    _('not removing %s: file is untracked\n') % uipathfn(f)
+                )
         # missing files will generate a warning elsewhere
         ret = 1
     progress.complete()
@@ -2299,40 +2594,52 @@
     elif after:
         list = deleted
         remaining = modified + added + clean
-        progress = ui.makeprogress(_('skipping'), total=len(remaining),
-                                   unit=_('files'))
+        progress = ui.makeprogress(
+            _('skipping'), total=len(remaining), unit=_('files')
+        )
         for f in remaining:
             progress.increment()
             if ui.verbose or (f in files):
-                warnings.append(_('not removing %s: file still exists\n')
-                                % uipathfn(f))
+                warnings.append(
+                    _('not removing %s: file still exists\n') % uipathfn(f)
+                )
             ret = 1
         progress.complete()
     else:
         list = deleted + clean
-        progress = ui.makeprogress(_('skipping'),
-                                   total=(len(modified) + len(added)),
-                                   unit=_('files'))
+        progress = ui.makeprogress(
+            _('skipping'), total=(len(modified) + len(added)), unit=_('files')
+        )
         for f in modified:
             progress.increment()
-            warnings.append(_('not removing %s: file is modified (use -f'
-                      ' to force removal)\n') % uipathfn(f))
+            warnings.append(
+                _(
+                    'not removing %s: file is modified (use -f'
+                    ' to force removal)\n'
+                )
+                % uipathfn(f)
+            )
             ret = 1
         for f in added:
             progress.increment()
-            warnings.append(_("not removing %s: file has been marked for add"
-                      " (use 'hg forget' to undo add)\n") % uipathfn(f))
+            warnings.append(
+                _(
+                    "not removing %s: file has been marked for add"
+                    " (use 'hg forget' to undo add)\n"
+                )
+                % uipathfn(f)
+            )
             ret = 1
         progress.complete()
 
     list = sorted(list)
-    progress = ui.makeprogress(_('deleting'), total=len(list),
-                               unit=_('files'))
+    progress = ui.makeprogress(_('deleting'), total=len(list), unit=_('files'))
     for f in list:
         if ui.verbose or not m.exact(f):
             progress.increment()
-            ui.status(_('removing %s\n') % uipathfn(f),
-                      label='ui.addremove.removed')
+            ui.status(
+                _('removing %s\n') % uipathfn(f), label='ui.addremove.removed'
+            )
     progress.complete()
 
     if not dryrun:
@@ -2340,9 +2647,10 @@
             if not after:
                 for f in list:
                     if f in added:
-                        continue # we never unlink added files on remove
-                    rmdir = repo.ui.configbool('experimental',
-                                               'removeemptydirs')
+                        continue  # we never unlink added files on remove
+                    rmdir = repo.ui.configbool(
+                        'experimental', 'removeemptydirs'
+                    )
                     repo.wvfs.unlinkpath(f, ignoremissing=True, rmdir=rmdir)
             repo[None].forget(list)
 
@@ -2352,9 +2660,11 @@
 
     return ret
 
+
 def _catfmtneedsdata(fm):
     return not fm.datahint() or 'data' in fm.datahint()
 
+
 def _updatecatformatter(fm, ctx, matcher, path, decode):
     """Hook for adding data to the formatter used by ``hg cat``.
 
@@ -2373,6 +2683,7 @@
     fm.write('data', '%s', data)
     fm.data(path=path)
 
+
 def cat(ui, repo, ctx, matcher, basefm, fntemplate, prefix, **opts):
     err = 1
     opts = pycompat.byteskwargs(opts)
@@ -2380,8 +2691,9 @@
     def write(path):
         filename = None
         if fntemplate:
-            filename = makefilename(ctx, fntemplate,
-                                    pathname=os.path.join(prefix, path))
+            filename = makefilename(
+                ctx, fntemplate, pathname=os.path.join(prefix, path)
+            )
             # attempt to create the directory if it does not already exist
             try:
                 os.makedirs(os.path.dirname(filename))
@@ -2418,15 +2730,22 @@
         try:
             submatch = matchmod.subdirmatcher(subpath, matcher)
             subprefix = os.path.join(prefix, subpath)
-            if not sub.cat(submatch, basefm, fntemplate, subprefix,
-                           **pycompat.strkwargs(opts)):
+            if not sub.cat(
+                submatch,
+                basefm,
+                fntemplate,
+                subprefix,
+                **pycompat.strkwargs(opts)
+            ):
                 err = 0
         except error.RepoLookupError:
-            ui.status(_("skipping missing subrepository: %s\n") %
-                      uipathfn(subpath))
+            ui.status(
+                _("skipping missing subrepository: %s\n") % uipathfn(subpath)
+            )
 
     return err
 
+
 def commit(ui, repo, commitfunc, pats, opts):
     '''commit the specified files or all outstanding changes'''
     date = opts.get('date')
@@ -2446,22 +2765,24 @@
             uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=relative)
             if scmutil.addremove(repo, matcher, "", uipathfn, opts) != 0:
                 raise error.Abort(
-                    _("failed to mark all new/missing files as added/removed"))
+                    _("failed to mark all new/missing files as added/removed")
+                )
 
         return commitfunc(ui, repo, message, matcher, opts)
 
+
 def samefile(f, ctx1, ctx2):
     if f in ctx1.manifest():
         a = ctx1.filectx(f)
         if f in ctx2.manifest():
             b = ctx2.filectx(f)
-            return (not a.cmp(b)
-                    and a.flags() == b.flags())
+            return not a.cmp(b) and a.flags() == b.flags()
         else:
             return False
     else:
         return f not in ctx2.manifest()
 
+
 def amend(ui, repo, old, extra, pats, opts):
     # avoid cycle context -> subrepo -> cmdutil
     from . import context
@@ -2469,7 +2790,7 @@
     # amend will reuse the existing user if not specified, but the obsolete
     # marker creation requires that the current user's name is specified.
     if obsolete.isenabled(repo, obsolete.createmarkersopt):
-        ui.username() # raise exception if username not set
+        ui.username()  # raise exception if username not set
 
     ui.note(_('amending changeset %s\n') % old)
     base = old.p1()
@@ -2514,17 +2835,20 @@
         matcher = scmutil.match(wctx, pats, opts)
         relative = scmutil.anypats(pats, opts)
         uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=relative)
-        if (opts.get('addremove')
-            and scmutil.addremove(repo, matcher, "", uipathfn, opts)):
+        if opts.get('addremove') and scmutil.addremove(
+            repo, matcher, "", uipathfn, opts
+        ):
             raise error.Abort(
-                _("failed to mark all new/missing files as added/removed"))
+                _("failed to mark all new/missing files as added/removed")
+            )
 
         # Check subrepos. This depends on in-place wctx._status update in
         # subrepo.precommit(). To minimize the risk of this hack, we do
         # nothing if .hgsub does not exist.
         if '.hgsub' in wctx or '.hgsub' in old:
             subs, commitsubs, newsubstate = subrepoutil.precommit(
-                ui, wctx, wctx._status, matcher)
+                ui, wctx, wctx._status, matcher
+            )
             # amend should abort if commitsubrepos is enabled
             assert not commitsubs
             if subs:
@@ -2535,7 +2859,7 @@
 
         filestoamend = set(f for f in wctx.files() if matcher(f))
 
-        changes = (len(filestoamend) > 0)
+        changes = len(filestoamend) > 0
         if changes:
             # Recompute copies (avoid recording a -> b -> a)
             copied = copies.pathcopies(base, wctx, matcher)
@@ -2549,8 +2873,11 @@
             # was removed, it's no longer relevant. If X is missing (aka
             # deleted), old X must be preserved.
             files.update(filestoamend)
-            files = [f for f in files if (f not in filestoamend
-                                          or not samefile(f, wctx, base))]
+            files = [
+                f
+                for f in files
+                if (f not in filestoamend or not samefile(f, wctx, base))
+            ]
 
             def filectxfn(repo, ctx_, path):
                 try:
@@ -2568,14 +2895,19 @@
 
                     fctx = wctx[path]
                     flags = fctx.flags()
-                    mctx = context.memfilectx(repo, ctx_,
-                                              fctx.path(), fctx.data(),
-                                              islink='l' in flags,
-                                              isexec='x' in flags,
-                                              copysource=copied.get(path))
+                    mctx = context.memfilectx(
+                        repo,
+                        ctx_,
+                        fctx.path(),
+                        fctx.data(),
+                        islink='l' in flags,
+                        isexec='x' in flags,
+                        copysource=copied.get(path),
+                    )
                     return mctx
                 except KeyError:
                     return None
+
         else:
             ui.note(_('copying changeset %s to %s\n') % (old, base))
 
@@ -2607,22 +2939,26 @@
         pureextra = extra.copy()
         extra['amend_source'] = old.hex()
 
-        new = context.memctx(repo,
-                             parents=[base.node(), old.p2().node()],
-                             text=message,
-                             files=files,
-                             filectxfn=filectxfn,
-                             user=user,
-                             date=date,
-                             extra=extra,
-                             editor=editor)
+        new = context.memctx(
+            repo,
+            parents=[base.node(), old.p2().node()],
+            text=message,
+            files=files,
+            filectxfn=filectxfn,
+            user=user,
+            date=date,
+            extra=extra,
+            editor=editor,
+        )
 
         newdesc = changelog.stripdesc(new.description())
-        if ((not changes)
+        if (
+            (not changes)
             and newdesc == old.description()
             and user == old.user()
             and (date == old.date() or datemaydiffer)
-            and pureextra == old.extra()):
+            and pureextra == old.extra()
+        ):
             # nothing changed. continuing here would create a new node
             # anyway because of the amend_source noise.
             #
@@ -2641,9 +2977,15 @@
         if opts.get('note'):
             obsmetadata = {'note': encoding.fromlocal(opts['note'])}
         backup = ui.configbool('rewrite', 'backup-bundle')
-        scmutil.cleanupnodes(repo, mapping, 'amend', metadata=obsmetadata,
-                             fixphase=True, targetphase=commitphase,
-                             backup=backup)
+        scmutil.cleanupnodes(
+            repo,
+            mapping,
+            'amend',
+            metadata=obsmetadata,
+            fixphase=True,
+            targetphase=commitphase,
+            backup=backup,
+        )
 
         # Fixing the dirstate because localrepo.commitctx does not update
         # it. This is rather convenient because we did not need to update
@@ -2666,14 +3008,24 @@
 
     return newid
 
+
 def commiteditor(repo, ctx, subs, editform=''):
     if ctx.description():
         return ctx.description()
-    return commitforceeditor(repo, ctx, subs, editform=editform,
-                             unchangedmessagedetection=True)
-
-def commitforceeditor(repo, ctx, subs, finishdesc=None, extramsg=None,
-                      editform='', unchangedmessagedetection=False):
+    return commitforceeditor(
+        repo, ctx, subs, editform=editform, unchangedmessagedetection=True
+    )
+
+
+def commitforceeditor(
+    repo,
+    ctx,
+    subs,
+    finishdesc=None,
+    extramsg=None,
+    editform='',
+    unchangedmessagedetection=False,
+):
     if not extramsg:
         extramsg = _("Leave message empty to abort commit.")
 
@@ -2684,7 +3036,8 @@
         ref = '.'.join(forms)
         if repo.ui.config('committemplate', ref):
             templatetext = committext = buildcommittemplate(
-                repo, ctx, subs, extramsg, ref)
+                repo, ctx, subs, extramsg, ref
+            )
             break
         forms.pop()
     else:
@@ -2699,16 +3052,22 @@
     repo.dirstate.write(tr)
     pending = tr and tr.writepending() and repo.root
 
-    editortext = repo.ui.edit(committext, ctx.user(), ctx.extra(),
-                              editform=editform, pending=pending,
-                              repopath=repo.path, action='commit')
+    editortext = repo.ui.edit(
+        committext,
+        ctx.user(),
+        ctx.extra(),
+        editform=editform,
+        pending=pending,
+        repopath=repo.path,
+        action='commit',
+    )
     text = editortext
 
     # strip away anything below this special string (used for editors that want
     # to display the diff)
     stripbelow = re.search(_linebelow, text, flags=re.MULTILINE)
     if stripbelow:
-        text = text[:stripbelow.start()]
+        text = text[: stripbelow.start()]
 
     text = re.sub("(?m)^HG:.*(\n|$)", "", text)
     os.chdir(olddir)
@@ -2722,32 +3081,43 @@
 
     return text
 
+
 def buildcommittemplate(repo, ctx, subs, extramsg, ref):
     ui = repo.ui
     spec = formatter.templatespec(ref, None, None)
     t = logcmdutil.changesettemplater(ui, repo, spec)
-    t.t.cache.update((k, templater.unquotestring(v))
-                     for k, v in repo.ui.configitems('committemplate'))
+    t.t.cache.update(
+        (k, templater.unquotestring(v))
+        for k, v in repo.ui.configitems('committemplate')
+    )
 
     if not extramsg:
-        extramsg = '' # ensure that extramsg is string
+        extramsg = ''  # ensure that extramsg is string
 
     ui.pushbuffer()
     t.show(ctx, extramsg=extramsg)
     return ui.popbuffer()
 
+
 def hgprefix(msg):
     return "\n".join(["HG: %s" % a for a in msg.split("\n") if a])
 
+
 def buildcommittext(repo, ctx, subs, extramsg):
     edittext = []
     modified, added, removed = ctx.modified(), ctx.added(), ctx.removed()
     if ctx.description():
         edittext.append(ctx.description())
     edittext.append("")
-    edittext.append("") # Empty line between message and comments.
-    edittext.append(hgprefix(_("Enter commit message."
-                      "  Lines beginning with 'HG:' are removed.")))
+    edittext.append("")  # Empty line between message and comments.
+    edittext.append(
+        hgprefix(
+            _(
+                "Enter commit message."
+                "  Lines beginning with 'HG:' are removed."
+            )
+        )
+    )
     edittext.append(hgprefix(extramsg))
     edittext.append("HG: --")
     edittext.append(hgprefix(_("user: %s") % ctx.user()))
@@ -2767,14 +3137,21 @@
 
     return "\n".join(edittext)
 
+
 def commitstatus(repo, node, branch, bheads=None, opts=None):
     if opts is None:
         opts = {}
     ctx = repo[node]
     parents = ctx.parents()
 
-    if (not opts.get('amend') and bheads and node not in bheads and not
-        [x for x in parents if x.node() in bheads and x.branch() == branch]):
+    if (
+        not opts.get('amend')
+        and bheads
+        and node not in bheads
+        and not [
+            x for x in parents if x.node() in bheads and x.branch() == branch
+        ]
+    ):
         repo.ui.status(_('created new head\n'))
         # The message is not printed for initial roots. For the other
         # changesets, it is printed in the following situations:
@@ -2815,9 +3192,11 @@
     elif repo.ui.verbose:
         repo.ui.write(_('committed changeset %d:%s\n') % (ctx.rev(), ctx))
 
+
 def postcommitstatus(repo, pats, opts):
     return repo.status(match=scmutil.match(repo[None], pats, opts))
 
+
 def revert(ui, repo, ctx, parents, *pats, **opts):
     opts = pycompat.byteskwargs(opts)
     parent, p2 = parents
@@ -2875,8 +3254,9 @@
             # Find status of all file in `names`.
             m = scmutil.matchfiles(repo, names)
 
-            changes = repo.status(node1=node, match=m,
-                                  unknown=True, ignored=True, clean=True)
+            changes = repo.status(
+                node1=node, match=m, unknown=True, ignored=True, clean=True
+            )
         else:
             changes = repo.status(node1=node, match=m)
             for kind in changes:
@@ -2886,12 +3266,12 @@
             m = scmutil.matchfiles(repo, names)
 
         modified = set(changes.modified)
-        added    = set(changes.added)
-        removed  = set(changes.removed)
+        added = set(changes.added)
+        removed = set(changes.removed)
         _deleted = set(changes.deleted)
-        unknown  = set(changes.unknown)
+        unknown = set(changes.unknown)
         unknown.update(changes.ignored)
-        clean    = set(changes.clean)
+        clean = set(changes.clean)
         modadded = set()
 
         # We need to account for the state of the file in the dirstate,
@@ -2908,8 +3288,8 @@
         else:
             changes = repo.status(node1=parent, match=m)
             dsmodified = set(changes.modified)
-            dsadded    = set(changes.added)
-            dsremoved  = set(changes.removed)
+            dsadded = set(changes.added)
+            dsremoved = set(changes.removed)
             # store all local modifications, useful later for rename detection
             localchanges = dsmodified | dsadded
 
@@ -2924,7 +3304,7 @@
 
             # tell newly modified apart.
             dsmodified &= modified
-            dsmodified |= modified & dsadded # dirstate added may need backup
+            dsmodified |= modified & dsadded  # dirstate added may need backup
             modified -= dsmodified
 
             # We need to wait for some post-processing to update this set
@@ -2989,24 +3369,25 @@
 
         # action to be actually performed by revert
         # (<list of file>, message>) tuple
-        actions = {'revert': ([], _('reverting %s\n')),
-                   'add': ([], _('adding %s\n')),
-                   'remove': ([], _('removing %s\n')),
-                   'drop': ([], _('removing %s\n')),
-                   'forget': ([], _('forgetting %s\n')),
-                   'undelete': ([], _('undeleting %s\n')),
-                   'noop': (None, _('no changes needed to %s\n')),
-                   'unknown': (None, _('file not managed: %s\n')),
-                  }
+        actions = {
+            'revert': ([], _('reverting %s\n')),
+            'add': ([], _('adding %s\n')),
+            'remove': ([], _('removing %s\n')),
+            'drop': ([], _('removing %s\n')),
+            'forget': ([], _('forgetting %s\n')),
+            'undelete': ([], _('undeleting %s\n')),
+            'noop': (None, _('no changes needed to %s\n')),
+            'unknown': (None, _('file not managed: %s\n')),
+        }
 
         # "constant" that convey the backup strategy.
         # All set to `discard` if `no-backup` is set do avoid checking
         # no_backup lower in the code.
         # These values are ordered for comparison purposes
-        backupinteractive = 3 # do backup if interactively modified
+        backupinteractive = 3  # do backup if interactively modified
         backup = 2  # unconditionally do backup
-        check = 1   # check if the existing file differs from target
-        discard = 0 # never do backup
+        check = 1  # check if the existing file differs from target
+        discard = 0  # never do backup
         if opts.get('no_backup'):
             backupinteractive = backup = check = discard
         if interactive:
@@ -3024,36 +3405,35 @@
             #   file state
             #   action
             #   make backup
-
             ## Sets that results that will change file on disk
             # Modified compared to target, no local change
-            (modified,      actions['revert'],   discard),
+            (modified, actions['revert'], discard),
             # Modified compared to target, but local file is deleted
-            (deleted,       actions['revert'],   discard),
+            (deleted, actions['revert'], discard),
             # Modified compared to target, local change
-            (dsmodified,    actions['revert'],   dsmodifiedbackup),
+            (dsmodified, actions['revert'], dsmodifiedbackup),
             # Added since target
-            (added,         actions['remove'],   discard),
+            (added, actions['remove'], discard),
             # Added in working directory
-            (dsadded,       actions['forget'],   discard),
+            (dsadded, actions['forget'], discard),
             # Added since target, have local modification
-            (modadded,      backupanddel,        backup),
+            (modadded, backupanddel, backup),
             # Added since target but file is missing in working directory
-            (deladded,      actions['drop'],   discard),
+            (deladded, actions['drop'], discard),
             # Removed since  target, before working copy parent
-            (removed,       actions['add'],      discard),
+            (removed, actions['add'], discard),
             # Same as `removed` but an unknown file exists at the same path
-            (removunk,      actions['add'],      check),
+            (removunk, actions['add'], check),
             # Removed since targe, marked as such in working copy parent
-            (dsremoved,     actions['undelete'], discard),
+            (dsremoved, actions['undelete'], discard),
             # Same as `dsremoved` but an unknown file exists at the same path
-            (dsremovunk,    actions['undelete'], check),
+            (dsremovunk, actions['undelete'], check),
             ## the following sets does not result in any file changes
             # File with no modification
-            (clean,         actions['noop'],     discard),
+            (clean, actions['noop'], discard),
             # Existing file, not tracked anywhere
-            (unknown,       actions['unknown'],  discard),
-            )
+            (unknown, actions['unknown'], discard),
+        )
 
         for abs, exact in sorted(names.items()):
             # target file to be touch on disk (relative to cwd)
@@ -3071,12 +3451,15 @@
                         # .orig files (issue4793)
                         if dobackup == backupinteractive:
                             tobackup.add(abs)
-                        elif (backup <= dobackup or wctx[abs].cmp(ctx[abs])):
+                        elif backup <= dobackup or wctx[abs].cmp(ctx[abs]):
                             absbakname = scmutil.backuppath(ui, repo, abs)
-                            bakname = os.path.relpath(absbakname,
-                                                      start=repo.root)
-                            ui.note(_('saving current version of %s as %s\n') %
-                                    (uipathfn(abs), uipathfn(bakname)))
+                            bakname = os.path.relpath(
+                                absbakname, start=repo.root
+                            )
+                            ui.note(
+                                _('saving current version of %s as %s\n')
+                                % (uipathfn(abs), uipathfn(bakname))
+                            )
                             if not opts.get('dry_run'):
                                 if interactive:
                                     util.copyfile(target, absbakname)
@@ -3094,25 +3477,49 @@
             oplist = [actions[name][0] for name in needdata]
             prefetch = scmutil.prefetchfiles
             matchfiles = scmutil.matchfiles
-            prefetch(repo, [ctx.rev()],
-                     matchfiles(repo,
-                                [f for sublist in oplist for f in sublist]))
+            prefetch(
+                repo,
+                [ctx.rev()],
+                matchfiles(repo, [f for sublist in oplist for f in sublist]),
+            )
             match = scmutil.match(repo[None], pats)
-            _performrevert(repo, parents, ctx, names, uipathfn, actions,
-                           match, interactive, tobackup)
+            _performrevert(
+                repo,
+                parents,
+                ctx,
+                names,
+                uipathfn,
+                actions,
+                match,
+                interactive,
+                tobackup,
+            )
 
         if targetsubs:
             # Revert the subrepos on the revert list
             for sub in targetsubs:
                 try:
-                    wctx.sub(sub).revert(ctx.substate[sub], *pats,
-                                         **pycompat.strkwargs(opts))
+                    wctx.sub(sub).revert(
+                        ctx.substate[sub], *pats, **pycompat.strkwargs(opts)
+                    )
                 except KeyError:
-                    raise error.Abort("subrepository '%s' does not exist in %s!"
-                                      % (sub, short(ctx.node())))
-
-def _performrevert(repo, parents, ctx, names, uipathfn, actions,
-                   match, interactive=False, tobackup=None):
+                    raise error.Abort(
+                        "subrepository '%s' does not exist in %s!"
+                        % (sub, short(ctx.node()))
+                    )
+
+
+def _performrevert(
+    repo,
+    parents,
+    ctx,
+    names,
+    uipathfn,
+    actions,
+    match,
+    interactive=False,
+    tobackup=None,
+):
     """function that actually perform all the actions computed for revert
 
     This is an independent function to let extension to plug in and react to
@@ -3145,7 +3552,8 @@
     for f in actions['forget'][0]:
         if interactive:
             choice = repo.ui.promptchoice(
-                _("forget added file %s (Yn)?$$ &Yes $$ &No") % uipathfn(f))
+                _("forget added file %s (Yn)?$$ &Yes $$ &No") % uipathfn(f)
+            )
             if choice == 0:
                 prntstatusmsg('forget', f)
                 repo.dirstate.drop(f)
@@ -3158,7 +3566,8 @@
         audit_path(f)
         if interactive:
             choice = repo.ui.promptchoice(
-                _("remove added file %s (Yn)?$$ &Yes $$ &No") % uipathfn(f))
+                _("remove added file %s (Yn)?$$ &Yes $$ &No") % uipathfn(f)
+            )
             if choice == 0:
                 prntstatusmsg('remove', f)
                 doremove(f)
@@ -3187,15 +3596,19 @@
         # Prompt the user for changes to revert
         torevert = [f for f in actions['revert'][0] if f not in excluded_files]
         m = scmutil.matchfiles(repo, torevert)
-        diffopts = patch.difffeatureopts(repo.ui, whitespace=True,
-                                         section='commands',
-                                         configprefix='revert.interactive.')
+        diffopts = patch.difffeatureopts(
+            repo.ui,
+            whitespace=True,
+            section='commands',
+            configprefix='revert.interactive.',
+        )
         diffopts.nodates = True
         diffopts.git = True
         operation = 'apply'
         if node == parent:
-            if repo.ui.configbool('experimental',
-                                  'revert.interactive.select-to-keep'):
+            if repo.ui.configbool(
+                'experimental', 'revert.interactive.select-to-keep'
+            ):
                 operation = 'keep'
             else:
                 operation = 'discard'
@@ -3208,8 +3621,9 @@
 
         try:
 
-            chunks, opts = recordfilter(repo.ui, originalchunks, match,
-                                        operation=operation)
+            chunks, opts = recordfilter(
+                repo.ui, originalchunks, match, operation=operation
+            )
             if operation == 'discard':
                 chunks = patch.reversehunks(chunks)
 
@@ -3222,7 +3636,8 @@
         # alsorestore value. Ideally we'd be able to partially revert
         # copied/renamed files.
         newlyaddedandmodifiedfiles, unusedalsorestore = newandmodified(
-                chunks, originalchunks)
+            chunks, originalchunks
+        )
         if tobackup is None:
             tobackup = set()
         # Apply changes
@@ -3273,7 +3688,8 @@
     for f in actions['undelete'][0]:
         if interactive:
             choice = repo.ui.promptchoice(
-                _("add back removed file %s (Yn)?$$ &Yes $$ &No") % f)
+                _("add back removed file %s (Yn)?$$ &Yes $$ &No") % f
+            )
             if choice == 0:
                 prntstatusmsg('undelete', f)
                 checkout(f)
@@ -3291,6 +3707,7 @@
         if f in copied:
             repo.dirstate.copy(copied[f], f)
 
+
 # a list of (ui, repo, otherpeer, opts, missing) functions called by
 # commands.outgoing.  "missing" is "missing" of the result of
 # "findcommonoutgoing()"
@@ -3318,19 +3735,27 @@
     # Check for non-clearable states first, so things like rebase will take
     # precedence over update.
     for state in statemod._unfinishedstates:
-        if (state._clearable or (commit and state._allowcommit) or
-            state._reportonly):
+        if (
+            state._clearable
+            or (commit and state._allowcommit)
+            or state._reportonly
+        ):
             continue
         if state.isunfinished(repo):
             raise error.Abort(state.msg(), hint=state.hint())
 
     for s in statemod._unfinishedstates:
-        if (not s._clearable or (commit and s._allowcommit) or
-            (s._opname == 'merge' and skipmerge) or s._reportonly):
+        if (
+            not s._clearable
+            or (commit and s._allowcommit)
+            or (s._opname == 'merge' and skipmerge)
+            or s._reportonly
+        ):
             continue
         if s.isunfinished(repo):
             raise error.Abort(s.msg(), hint=s.hint())
 
+
 def clearunfinished(repo):
     '''Check for unfinished operations (as above), and clear the ones
     that are clearable.
@@ -3347,6 +3772,7 @@
         if s._clearable and s.isunfinished(repo):
             util.unlink(repo.vfs.join(s._fname))
 
+
 def getunfinishedstate(repo):
     ''' Checks for unfinished operations and returns statecheck object
         for it'''
@@ -3355,6 +3781,7 @@
             return state
     return None
 
+
 def howtocontinue(repo):
     '''Check for an unfinished operation and return the command to finish
     it.
@@ -3376,6 +3803,7 @@
         return contmsg % _("hg commit"), False
     return None, None
 
+
 def checkafterresolved(repo):
     '''Inform the user about the next action after completing hg resolve
 
@@ -3391,6 +3819,7 @@
         else:
             repo.ui.note("%s\n" % msg)
 
+
 def wrongtooltocontinue(repo, task):
     '''Raise an abort suggesting how to properly continue if there is an
     active task.
@@ -3406,6 +3835,7 @@
         hint = after[0]
     raise error.Abort(_('no %s in progress') % task, hint=hint)
 
+
 def abortgraft(ui, repo, graftstate):
     """abort the interrupted graft and rollbacks to the state before interrupted
     graft"""
@@ -3426,30 +3856,38 @@
     # whether to strip or not
     cleanup = False
     from . import hg
+
     if newnodes:
         newnodes = [repo[r].rev() for r in newnodes]
         cleanup = True
         # checking that none of the newnodes turned public or is public
         immutable = [c for c in newnodes if not repo[c].mutable()]
         if immutable:
-            repo.ui.warn(_("cannot clean up public changesets %s\n")
-                         % ', '.join(bytes(repo[r]) for r in immutable),
-                         hint=_("see 'hg help phases' for details"))
+            repo.ui.warn(
+                _("cannot clean up public changesets %s\n")
+                % ', '.join(bytes(repo[r]) for r in immutable),
+                hint=_("see 'hg help phases' for details"),
+            )
             cleanup = False
 
         # checking that no new nodes are created on top of grafted revs
         desc = set(repo.changelog.descendants(newnodes))
         if desc - set(newnodes):
-            repo.ui.warn(_("new changesets detected on destination "
-                           "branch, can't strip\n"))
+            repo.ui.warn(
+                _(
+                    "new changesets detected on destination "
+                    "branch, can't strip\n"
+                )
+            )
             cleanup = False
 
         if cleanup:
             with repo.wlock(), repo.lock():
                 hg.updaterepo(repo, startctx.node(), overwrite=True)
                 # stripping the new nodes created
-                strippoints = [c.node() for c in repo.set("roots(%ld)",
-                                                          newnodes)]
+                strippoints = [
+                    c.node() for c in repo.set("roots(%ld)", newnodes)
+                ]
                 repair.strip(repo.ui, repo, strippoints, backup=False)
 
     if not cleanup:
@@ -3462,6 +3900,7 @@
     graftstate.delete()
     return 0
 
+
 def readgraftstate(repo, graftstate):
     """read the graft state file and return a dict of the data stored in it"""
     try:
@@ -3470,6 +3909,7 @@
         nodes = repo.vfs.read('graftstate').splitlines()
         return {'nodes': nodes}
 
+
 def hgabortgraft(ui, repo):
     """ abort logic for aborting graft using 'hg abort'"""
     with repo.wlock():