mercurial/sparse.py
changeset 43077 687b865b95ad
parent 43076 2372284d9457
child 43106 d783f945a701
--- a/mercurial/sparse.py	Sun Oct 06 09:45:02 2019 -0400
+++ b/mercurial/sparse.py	Sun Oct 06 09:48:39 2019 -0400
@@ -44,49 +44,52 @@
     current = None
     havesection = False
 
-    for line in raw.split('\n'):
+    for line in raw.split(b'\n'):
         line = line.strip()
-        if not line or line.startswith('#'):
+        if not line or line.startswith(b'#'):
             # empty or comment line, skip
             continue
-        elif line.startswith('%include '):
+        elif line.startswith(b'%include '):
             line = line[9:].strip()
             if line:
                 profiles.add(line)
-        elif line == '[include]':
+        elif line == b'[include]':
             if havesection and current != includes:
                 # TODO pass filename into this API so we can report it.
                 raise error.Abort(
                     _(
-                        '%(action)s config cannot have includes '
-                        'after excludes'
+                        b'%(action)s config cannot have includes '
+                        b'after excludes'
                     )
-                    % {'action': action}
+                    % {b'action': action}
                 )
             havesection = True
             current = includes
             continue
-        elif line == '[exclude]':
+        elif line == b'[exclude]':
             havesection = True
             current = excludes
         elif line:
             if current is None:
                 raise error.Abort(
-                    _('%(action)s config entry outside of ' 'section: %(line)s')
-                    % {'action': action, 'line': line},
+                    _(
+                        b'%(action)s config entry outside of '
+                        b'section: %(line)s'
+                    )
+                    % {b'action': action, b'line': line},
                     hint=_(
-                        'add an [include] or [exclude] line '
-                        'to declare the entry type'
+                        b'add an [include] or [exclude] line '
+                        b'to declare the entry type'
                     ),
                 )
 
-            if line.strip().startswith('/'):
+            if line.strip().startswith(b'/'):
                 ui.warn(
                     _(
-                        'warning: %(action)s profile cannot use'
-                        ' paths starting with /, ignoring %(line)s\n'
+                        b'warning: %(action)s profile cannot use'
+                        b' paths starting with /, ignoring %(line)s\n'
                     )
-                    % {'action': action, 'line': line}
+                    % {b'action': action, b'line': line}
                 )
                 continue
             current.add(line)
@@ -112,16 +115,16 @@
     if not enabled:
         return set(), set(), set()
 
-    raw = repo.vfs.tryread('sparse')
+    raw = repo.vfs.tryread(b'sparse')
     if not raw:
         return set(), set(), set()
 
     if rev is None:
         raise error.Abort(
-            _('cannot parse sparse patterns from working ' 'directory')
+            _(b'cannot parse sparse patterns from working ' b'directory')
         )
 
-    includes, excludes, profiles = parseconfig(repo.ui, raw, 'sparse')
+    includes, excludes, profiles = parseconfig(repo.ui, raw, b'sparse')
     ctx = repo[rev]
 
     if profiles:
@@ -137,17 +140,19 @@
                 raw = readprofile(repo, profile, rev)
             except error.ManifestLookupError:
                 msg = (
-                    "warning: sparse profile '%s' not found "
-                    "in rev %s - ignoring it\n" % (profile, ctx)
+                    b"warning: sparse profile '%s' not found "
+                    b"in rev %s - ignoring it\n" % (profile, ctx)
                 )
                 # experimental config: sparse.missingwarning
-                if repo.ui.configbool('sparse', 'missingwarning'):
+                if repo.ui.configbool(b'sparse', b'missingwarning'):
                     repo.ui.warn(msg)
                 else:
                     repo.ui.debug(msg)
                 continue
 
-            pincludes, pexcludes, subprofs = parseconfig(repo.ui, raw, 'sparse')
+            pincludes, pexcludes, subprofs = parseconfig(
+                repo.ui, raw, b'sparse'
+            )
             includes.update(pincludes)
             excludes.update(pexcludes)
             profiles.update(subprofs)
@@ -155,7 +160,7 @@
         profiles = visited
 
     if includes:
-        includes.add('.hg*')
+        includes.add(b'.hg*')
 
     return includes, excludes, profiles
 
@@ -192,56 +197,56 @@
     """
     cache = repo._sparsesignaturecache
 
-    signature = cache.get('signature')
+    signature = cache.get(b'signature')
 
     if includetemp:
-        tempsignature = cache.get('tempsignature')
+        tempsignature = cache.get(b'tempsignature')
     else:
-        tempsignature = '0'
+        tempsignature = b'0'
 
     if signature is None or (includetemp and tempsignature is None):
-        signature = hex(hashlib.sha1(repo.vfs.tryread('sparse')).digest())
-        cache['signature'] = signature
+        signature = hex(hashlib.sha1(repo.vfs.tryread(b'sparse')).digest())
+        cache[b'signature'] = signature
 
         if includetemp:
-            raw = repo.vfs.tryread('tempsparse')
+            raw = repo.vfs.tryread(b'tempsparse')
             tempsignature = hex(hashlib.sha1(raw).digest())
-            cache['tempsignature'] = tempsignature
+            cache[b'tempsignature'] = tempsignature
 
-    return '%s %s' % (signature, tempsignature)
+    return b'%s %s' % (signature, tempsignature)
 
 
 def writeconfig(repo, includes, excludes, profiles):
     """Write the sparse config file given a sparse configuration."""
-    with repo.vfs('sparse', 'wb') as fh:
+    with repo.vfs(b'sparse', b'wb') as fh:
         for p in sorted(profiles):
-            fh.write('%%include %s\n' % p)
+            fh.write(b'%%include %s\n' % p)
 
         if includes:
-            fh.write('[include]\n')
+            fh.write(b'[include]\n')
             for i in sorted(includes):
                 fh.write(i)
-                fh.write('\n')
+                fh.write(b'\n')
 
         if excludes:
-            fh.write('[exclude]\n')
+            fh.write(b'[exclude]\n')
             for e in sorted(excludes):
                 fh.write(e)
-                fh.write('\n')
+                fh.write(b'\n')
 
     repo._sparsesignaturecache.clear()
 
 
 def readtemporaryincludes(repo):
-    raw = repo.vfs.tryread('tempsparse')
+    raw = repo.vfs.tryread(b'tempsparse')
     if not raw:
         return set()
 
-    return set(raw.split('\n'))
+    return set(raw.split(b'\n'))
 
 
 def writetemporaryincludes(repo, includes):
-    repo.vfs.write('tempsparse', '\n'.join(sorted(includes)))
+    repo.vfs.write(b'tempsparse', b'\n'.join(sorted(includes)))
     repo._sparsesignaturecache.clear()
 
 
@@ -253,7 +258,7 @@
 
 
 def prunetemporaryincludes(repo):
-    if not enabled or not repo.vfs.exists('tempsparse'):
+    if not enabled or not repo.vfs.exists(b'tempsparse'):
         return
 
     s = repo.status()
@@ -268,24 +273,25 @@
     tempincludes = readtemporaryincludes(repo)
     for file in tempincludes:
         if file in dirstate and not sparsematch(file):
-            message = _('dropping temporarily included sparse files')
+            message = _(b'dropping temporarily included sparse files')
             actions.append((file, None, message))
             dropped.append(file)
 
     typeactions = mergemod.emptyactions()
-    typeactions['r'] = actions
+    typeactions[b'r'] = actions
     mergemod.applyupdates(
-        repo, typeactions, repo[None], repo['.'], False, wantfiledata=False
+        repo, typeactions, repo[None], repo[b'.'], False, wantfiledata=False
     )
 
     # Fix dirstate
     for file in dropped:
         dirstate.drop(file)
 
-    repo.vfs.unlink('tempsparse')
+    repo.vfs.unlink(b'tempsparse')
     repo._sparsesignaturecache.clear()
     msg = _(
-        'cleaned up %d temporarily added file(s) from the ' 'sparse checkout\n'
+        b'cleaned up %d temporarily added file(s) from the '
+        b'sparse checkout\n'
     )
     repo.ui.status(msg % len(tempincludes))
 
@@ -293,8 +299,8 @@
 def forceincludematcher(matcher, includes):
     """Returns a matcher that returns true for any of the forced includes
     before testing against the actual matcher."""
-    kindpats = [('path', include, '') for include in includes]
-    includematcher = matchmod.includematcher('', kindpats)
+    kindpats = [(b'path', include, b'') for include in includes]
+    includematcher = matchmod.includematcher(b'', kindpats)
     return matchmod.unionmatcher([includematcher, matcher])
 
 
@@ -319,7 +325,7 @@
 
     signature = configsignature(repo, includetemp=includetemp)
 
-    key = '%s %s' % (signature, ' '.join(map(pycompat.bytestr, revs)))
+    key = b'%s %s' % (signature, b' '.join(map(pycompat.bytestr, revs)))
 
     result = repo._sparsematchercache.get(key)
     if result:
@@ -333,11 +339,11 @@
             if includes or excludes:
                 matcher = matchmod.match(
                     repo.root,
-                    '',
+                    b'',
                     [],
                     include=includes,
                     exclude=excludes,
-                    default='relpath',
+                    default=b'relpath',
                 )
                 matchers.append(matcher)
         except IOError:
@@ -388,17 +394,17 @@
         files.add(file)
         if sparsematch(file):
             prunedactions[file] = action
-        elif type == 'm':
+        elif type == b'm':
             temporaryfiles.append(file)
             prunedactions[file] = action
         elif branchmerge:
-            if type != 'k':
+            if type != b'k':
                 temporaryfiles.append(file)
                 prunedactions[file] = action
-        elif type == 'f':
+        elif type == b'f':
             prunedactions[file] = action
         elif file in wctx:
-            prunedactions[file] = ('r', args, msg)
+            prunedactions[file] = (b'r', args, msg)
 
         if branchmerge and type == mergemod.ACTION_MERGE:
             f1, f2, fa, move, anc = args
@@ -408,8 +414,8 @@
     if len(temporaryfiles) > 0:
         repo.ui.status(
             _(
-                'temporarily included %d file(s) in the sparse '
-                'checkout for merging\n'
+                b'temporarily included %d file(s) in the sparse '
+                b'checkout for merging\n'
             )
             % len(temporaryfiles)
         )
@@ -417,7 +423,7 @@
 
         # Add the new files to the working copy so they can be merged, etc
         actions = []
-        message = 'temporarily adding to sparse checkout'
+        message = b'temporarily adding to sparse checkout'
         wctxmanifest = repo[None].manifest()
         for file in temporaryfiles:
             if file in wctxmanifest:
@@ -425,9 +431,9 @@
                 actions.append((file, (fctx.flags(), False), message))
 
         typeactions = mergemod.emptyactions()
-        typeactions['g'] = actions
+        typeactions[b'g'] = actions
         mergemod.applyupdates(
-            repo, typeactions, repo[None], repo['.'], False, wantfiledata=False
+            repo, typeactions, repo[None], repo[b'.'], False, wantfiledata=False
         )
 
         dirstate = repo.dirstate
@@ -446,9 +452,9 @@
             new = sparsematch(file)
             if not old and new:
                 flags = mf.flags(file)
-                prunedactions[file] = ('g', (flags, False), '')
+                prunedactions[file] = (b'g', (flags, False), b'')
             elif old and not new:
-                prunedactions[file] = ('r', [], '')
+                prunedactions[file] = (b'r', [], b'')
 
     return prunedactions
 
@@ -472,17 +478,17 @@
 
     for f in pending:
         if not sparsematch(f):
-            repo.ui.warn(_("pending changes to '%s'\n") % f)
+            repo.ui.warn(_(b"pending changes to '%s'\n") % f)
             abort = not force
 
     if abort:
         raise error.Abort(
-            _('could not update sparseness due to pending ' 'changes')
+            _(b'could not update sparseness due to pending ' b'changes')
         )
 
     # Calculate actions
     dirstate = repo.dirstate
-    ctx = repo['.']
+    ctx = repo[b'.']
     added = []
     lookup = []
     dropped = []
@@ -499,29 +505,29 @@
         if (new and not old) or (old and new and not file in dirstate):
             fl = mf.flags(file)
             if repo.wvfs.exists(file):
-                actions[file] = ('e', (fl,), '')
+                actions[file] = (b'e', (fl,), b'')
                 lookup.append(file)
             else:
-                actions[file] = ('g', (fl, False), '')
+                actions[file] = (b'g', (fl, False), b'')
                 added.append(file)
         # Drop files that are newly excluded, or that still exist in
         # the dirstate.
         elif (old and not new) or (not old and not new and file in dirstate):
             dropped.append(file)
             if file not in pending:
-                actions[file] = ('r', [], '')
+                actions[file] = (b'r', [], b'')
 
     # Verify there are no pending changes in newly included files
     abort = False
     for file in lookup:
-        repo.ui.warn(_("pending changes to '%s'\n") % file)
+        repo.ui.warn(_(b"pending changes to '%s'\n") % file)
         abort = not force
     if abort:
         raise error.Abort(
             _(
-                'cannot change sparseness due to pending '
-                'changes (delete the files or use '
-                '--force to bring them back dirty)'
+                b'cannot change sparseness due to pending '
+                b'changes (delete the files or use '
+                b'--force to bring them back dirty)'
             )
         )
 
@@ -539,7 +545,7 @@
         typeactions[m].append((f, args, msg))
 
     mergemod.applyupdates(
-        repo, typeactions, repo[None], repo['.'], False, wantfiledata=False
+        repo, typeactions, repo[None], repo[b'.'], False, wantfiledata=False
     )
 
     # Fix dirstate
@@ -577,8 +583,8 @@
     repo, includes, excludes, profiles, force=False, removing=False
 ):
     """Update the sparse config and working directory state."""
-    raw = repo.vfs.tryread('sparse')
-    oldincludes, oldexcludes, oldprofiles = parseconfig(repo.ui, raw, 'sparse')
+    raw = repo.vfs.tryread(b'sparse')
+    oldincludes, oldexcludes, oldprofiles = parseconfig(repo.ui, raw, b'sparse')
 
     oldstatus = repo.status()
     oldmatch = matcher(repo)
@@ -592,11 +598,11 @@
     # updated. But this requires massive rework to matcher() and its
     # consumers.
 
-    if 'exp-sparse' in oldrequires and removing:
-        repo.requirements.discard('exp-sparse')
+    if b'exp-sparse' in oldrequires and removing:
+        repo.requirements.discard(b'exp-sparse')
         scmutil.writerequires(repo.vfs, repo.requirements)
-    elif 'exp-sparse' not in oldrequires:
-        repo.requirements.add('exp-sparse')
+    elif b'exp-sparse' not in oldrequires:
+        repo.requirements.add(b'exp-sparse')
         scmutil.writerequires(repo.vfs, repo.requirements)
 
     try:
@@ -618,8 +624,8 @@
     directory is refreshed, as needed.
     """
     with repo.wlock():
-        raw = repo.vfs.tryread('sparse')
-        includes, excludes, profiles = parseconfig(repo.ui, raw, 'sparse')
+        raw = repo.vfs.tryread(b'sparse')
+        includes, excludes, profiles = parseconfig(repo.ui, raw, b'sparse')
 
         if not includes and not excludes:
             return
@@ -635,19 +641,19 @@
     """
     with repo.wlock():
         # read current configuration
-        raw = repo.vfs.tryread('sparse')
-        includes, excludes, profiles = parseconfig(repo.ui, raw, 'sparse')
+        raw = repo.vfs.tryread(b'sparse')
+        includes, excludes, profiles = parseconfig(repo.ui, raw, b'sparse')
         aincludes, aexcludes, aprofiles = activeconfig(repo)
 
         # Import rules on top; only take in rules that are not yet
         # part of the active rules.
         changed = False
         for p in paths:
-            with util.posixfile(util.expandpath(p), mode='rb') as fh:
+            with util.posixfile(util.expandpath(p), mode=b'rb') as fh:
                 raw = fh.read()
 
             iincludes, iexcludes, iprofiles = parseconfig(
-                repo.ui, raw, 'sparse'
+                repo.ui, raw, b'sparse'
             )
             oldsize = len(includes) + len(excludes) + len(profiles)
             includes.update(iincludes - aincludes)
@@ -696,9 +702,9 @@
     The new config is written out and a working directory refresh is performed.
     """
     with repo.wlock():
-        raw = repo.vfs.tryread('sparse')
+        raw = repo.vfs.tryread(b'sparse')
         oldinclude, oldexclude, oldprofiles = parseconfig(
-            repo.ui, raw, 'sparse'
+            repo.ui, raw, b'sparse'
         )
 
         if reset:
@@ -711,7 +717,7 @@
             newprofiles = set(oldprofiles)
 
         if any(os.path.isabs(pat) for pat in pats):
-            raise error.Abort(_('paths cannot be absolute'))
+            raise error.Abort(_(b'paths cannot be absolute'))
 
         if not usereporootpaths:
             # let's treat paths as relative to cwd
@@ -720,7 +726,7 @@
             for kindpat in pats:
                 kind, pat = matchmod._patsplit(kindpat, None)
                 if kind in matchmod.cwdrelativepatternkinds or kind is None:
-                    ap = (kind + ':' if kind else '') + pathutil.canonpath(
+                    ap = (kind + b':' if kind else b'') + pathutil.canonpath(
                         root, cwd, pat
                     )
                     abspats.append(ap)
@@ -778,24 +784,24 @@
     conflicting=0,
 ):
     """Print output summarizing sparse config changes."""
-    with ui.formatter('sparse', opts) as fm:
+    with ui.formatter(b'sparse', opts) as fm:
         fm.startitem()
         fm.condwrite(
             ui.verbose,
-            'profiles_added',
-            _('Profiles changed: %d\n'),
+            b'profiles_added',
+            _(b'Profiles changed: %d\n'),
             profilecount,
         )
         fm.condwrite(
             ui.verbose,
-            'include_rules_added',
-            _('Include rules changed: %d\n'),
+            b'include_rules_added',
+            _(b'Include rules changed: %d\n'),
             includecount,
         )
         fm.condwrite(
             ui.verbose,
-            'exclude_rules_added',
-            _('Exclude rules changed: %d\n'),
+            b'exclude_rules_added',
+            _(b'Exclude rules changed: %d\n'),
             excludecount,
         )
 
@@ -804,14 +810,14 @@
         # framework. No point in repeating ourselves in that case.
         if not fm.isplain():
             fm.condwrite(
-                ui.verbose, 'files_added', _('Files added: %d\n'), added
+                ui.verbose, b'files_added', _(b'Files added: %d\n'), added
             )
             fm.condwrite(
-                ui.verbose, 'files_dropped', _('Files dropped: %d\n'), dropped
+                ui.verbose, b'files_dropped', _(b'Files dropped: %d\n'), dropped
             )
             fm.condwrite(
                 ui.verbose,
-                'files_conflicting',
-                _('Files conflicting: %d\n'),
+                b'files_conflicting',
+                _(b'Files conflicting: %d\n'),
                 conflicting,
             )