diff -r 2372284d9457 -r 687b865b95ad mercurial/dirstate.py --- a/mercurial/dirstate.py Sun Oct 06 09:45:02 2019 -0400 +++ b/mercurial/dirstate.py Sun Oct 06 09:48:39 2019 -0400 @@ -87,8 +87,8 @@ self._ui = ui self._filecache = {} self._parentwriters = 0 - self._filename = 'dirstate' - self._pendingfilename = '%s.pending' % self._filename + self._filename = b'dirstate' + self._pendingfilename = b'%s.pending' % self._filename self._plchangecallbacks = {} self._origpl = None self._updatedfiles = set() @@ -140,14 +140,14 @@ # cache to keep the lookup fast.) return self._sparsematchfn() - @repocache('branch') + @repocache(b'branch') def _branch(self): try: - return self._opener.read("branch").strip() or "default" + return self._opener.read(b"branch").strip() or b"default" except IOError as inst: if inst.errno != errno.ENOENT: raise - return "default" + return b"default" @property def _pl(self): @@ -156,18 +156,18 @@ def hasdir(self, d): return self._map.hastrackeddir(d) - @rootcache('.hgignore') + @rootcache(b'.hgignore') def _ignore(self): files = self._ignorefiles() if not files: return matchmod.never() - pats = ['include:%s' % f for f in files] - return matchmod.match(self._root, '', [], pats, warn=self._ui.warn) + pats = [b'include:%s' % f for f in files] + return matchmod.match(self._root, b'', [], pats, warn=self._ui.warn) @propertycache def _slash(self): - return self._ui.configbool('ui', 'slash') and pycompat.ossep != '/' + return self._ui.configbool(b'ui', b'slash') and pycompat.ossep != b'/' @propertycache def _checklink(self): @@ -179,7 +179,7 @@ @propertycache def _checkcase(self): - return not util.fscasesensitive(self._join('.hg')) + return not util.fscasesensitive(self._join(b'.hg')) def _join(self, f): # much faster than os.path.join() @@ -193,12 +193,12 @@ try: st = os.lstat(self._join(x)) if util.statislink(st): - return 'l' + return b'l' if util.statisexec(st): - return 'x' + return b'x' except OSError: pass - return '' + return b'' return f @@ -207,20 +207,20 @@ def f(x): if os.path.islink(self._join(x)): - return 'l' - if 'x' in fallback(x): - return 'x' - return '' + return b'l' + if b'x' in fallback(x): + return b'x' + return b'' return f if self._checkexec: def f(x): - if 'l' in fallback(x): - return 'l' + if b'l' in fallback(x): + return b'l' if util.isexec(self._join(x)): - return 'x' - return '' + return b'x' + return b'' return f else: @@ -229,7 +229,7 @@ @propertycache def _cwd(self): # internal config: ui.forcecwd - forcecwd = self._ui.config('ui', 'forcecwd') + forcecwd = self._ui.config(b'ui', b'forcecwd') if forcecwd: return forcecwd return encoding.getcwd() @@ -243,7 +243,7 @@ ''' cwd = self._cwd if cwd == self._root: - return '' + return b'' # self._root ends with a path separator if self._root is '/' or 'C:\' rootsep = self._root if not util.endswithsep(rootsep): @@ -272,7 +272,7 @@ a marked for addition ? not tracked ''' - return self._map.get(key, ("?",))[0] + return self._map.get(key, (b"?",))[0] def __contains__(self, key): return key in self._map @@ -308,8 +308,8 @@ """ if self._parentwriters == 0: raise ValueError( - "cannot set dirstate parent outside of " - "dirstate.parentchange context manager" + b"cannot set dirstate parent outside of " + b"dirstate.parentchange context manager" ) self._dirty = True @@ -328,13 +328,13 @@ continue # Discard 'm' markers when moving away from a merge state - if s[0] == 'm': + if s[0] == b'm': source = self._map.copymap.get(f) if source: copies[f] = source self.normallookup(f) # Also fix up otherparent markers - elif s[0] == 'n' and s[2] == -2: + elif s[0] == b'n' and s[2] == -2: source = self._map.copymap.get(f) if source: copies[f] = source @@ -343,14 +343,14 @@ def setbranch(self, branch): self.__class__._branch.set(self, encoding.fromlocal(branch)) - f = self._opener('branch', 'w', atomictemp=True, checkambig=True) + f = self._opener(b'branch', b'w', atomictemp=True, checkambig=True) try: - f.write(self._branch + '\n') + f.write(self._branch + b'\n') f.close() # make sure filecache has the correct stat info for _branch after # replacing the underlying file - ce = self._filecache['_branch'] + ce = self._filecache[b'_branch'] if ce: ce.refresh() except: # re-raises @@ -393,20 +393,20 @@ def _addpath(self, f, state, mode, size, mtime): oldstate = self[f] - if state == 'a' or oldstate == 'r': + if state == b'a' or oldstate == b'r': scmutil.checkfilename(f) if self._map.hastrackeddir(f): raise error.Abort( - _('directory %r already in dirstate') % pycompat.bytestr(f) + _(b'directory %r already in dirstate') % pycompat.bytestr(f) ) # shadows for d in util.finddirs(f): if self._map.hastrackeddir(d): break entry = self._map.get(d) - if entry is not None and entry[0] != 'r': + if entry is not None and entry[0] != b'r': raise error.Abort( - _('file %r in dirstate clashes with %r') + _(b'file %r in dirstate clashes with %r') % (pycompat.bytestr(d), pycompat.bytestr(f)) ) self._dirty = True @@ -430,7 +430,7 @@ mode = s.st_mode size = s.st_size mtime = s[stat.ST_MTIME] - self._addpath(f, 'n', mode, size & _rangemask, mtime & _rangemask) + self._addpath(f, b'n', mode, size & _rangemask, mtime & _rangemask) self._map.copymap.pop(f, None) if f in self._map.nonnormalset: self._map.nonnormalset.remove(f) @@ -448,7 +448,7 @@ # being removed, restore that state. entry = self._map.get(f) if entry is not None: - if entry[0] == 'r' and entry[2] in (-1, -2): + if entry[0] == b'r' and entry[2] in (-1, -2): source = self._map.copymap.get(f) if entry[2] == -1: self.merge(f) @@ -457,28 +457,28 @@ if source: self.copy(source, f) return - if entry[0] == 'm' or entry[0] == 'n' and entry[2] == -2: + if entry[0] == b'm' or entry[0] == b'n' and entry[2] == -2: return - self._addpath(f, 'n', 0, -1, -1) + self._addpath(f, b'n', 0, -1, -1) self._map.copymap.pop(f, None) def otherparent(self, f): '''Mark as coming from the other parent, always dirty.''' if self._pl[1] == nullid: raise error.Abort( - _("setting %r to other parent " "only allowed in merges") % f + _(b"setting %r to other parent " b"only allowed in merges") % f ) - if f in self and self[f] == 'n': + if f in self and self[f] == b'n': # merge-like - self._addpath(f, 'm', 0, -2, -1) + self._addpath(f, b'm', 0, -2, -1) else: # add-like - self._addpath(f, 'n', 0, -2, -1) + self._addpath(f, b'n', 0, -2, -1) self._map.copymap.pop(f, None) def add(self, f): '''Mark a file added.''' - self._addpath(f, 'a', 0, -1, -1) + self._addpath(f, b'a', 0, -1, -1) self._map.copymap.pop(f, None) def remove(self, f): @@ -490,9 +490,9 @@ entry = self._map.get(f) if entry is not None: # backup the previous state - if entry[0] == 'm': # merge + if entry[0] == b'm': # merge size = -1 - elif entry[0] == 'n' and entry[2] == -2: # other parent + elif entry[0] == b'n' and entry[2] == -2: # other parent size = -2 self._map.otherparentset.add(f) self._updatedfiles.add(f) @@ -519,21 +519,21 @@ exists = os.path.lexists(os.path.join(self._root, path)) if not exists: # Maybe a path component exists - if not ignoremissing and '/' in path: - d, f = path.rsplit('/', 1) + if not ignoremissing and b'/' in path: + d, f = path.rsplit(b'/', 1) d = self._normalize(d, False, ignoremissing, None) - folded = d + "/" + f + folded = d + b"/" + f else: # No path components, preserve original case folded = path else: # recursively normalize leading directory components # against dirstate - if '/' in normed: - d, f = normed.rsplit('/', 1) + if b'/' in normed: + d, f = normed.rsplit(b'/', 1) d = self._normalize(d, False, ignoremissing, True) - r = self._root + "/" + d - folded = d + "/" + util.fspath(f, r) + r = self._root + b"/" + d + folded = d + b"/" + util.fspath(f, r) else: folded = util.fspath(normed, self._root) storemap[normed] = folded @@ -645,14 +645,14 @@ # delay writing in-memory changes out tr.addfilegenerator( - 'dirstate', + b'dirstate', (self._filename,), self._writedirstate, - location='plain', + location=b'plain', ) return - st = self._opener(filename, "w", atomictemp=True, checkambig=True) + st = self._opener(filename, b"w", atomictemp=True, checkambig=True) self._writedirstate(st) def addparentchangecallback(self, category, callback): @@ -678,12 +678,12 @@ # enough 'delaywrite' prevents 'pack_dirstate' from dropping # timestamp of each entries in dirstate, because of 'now > mtime' - delaywrite = self._ui.configint('debug', 'dirstate.delaywrite') + delaywrite = self._ui.configint(b'debug', b'dirstate.delaywrite') if delaywrite > 0: # do we have any files to delay for? items = self._map.iteritems() for f, e in items: - if e[0] == 'n' and e[3] == now: + if e[0] == b'n' and e[3] == now: import time # to avoid useless import # rather than sleep n seconds, sleep until the next @@ -715,10 +715,10 @@ def _ignorefiles(self): files = [] - if os.path.exists(self._join('.hgignore')): - files.append(self._join('.hgignore')) - for name, path in self._ui.configitems("ui"): - if name == 'ignore' or name.startswith('ignore.'): + if os.path.exists(self._join(b'.hgignore')): + files.append(self._join(b'.hgignore')) + for name, path in self._ui.configitems(b"ui"): + if name == b'ignore' or name.startswith(b'ignore.'): # we need to use os.path.join here rather than self._join # because path is arbitrary and user-specified files.append(os.path.join(self._rootdir, util.expandpath(path))) @@ -733,18 +733,18 @@ i, self._ui.warn, sourceinfo=True ) for pattern, lineno, line in patterns: - kind, p = matchmod._patsplit(pattern, 'glob') - if kind == "subinclude": + kind, p = matchmod._patsplit(pattern, b'glob') + if kind == b"subinclude": if p not in visited: files.append(p) continue m = matchmod.match( - self._root, '', [], [pattern], warn=self._ui.warn + self._root, b'', [], [pattern], warn=self._ui.warn ) if m(f): return (i, lineno, line) visited.add(i) - return (None, -1, "") + return (None, -1, b"") def _walkexplicit(self, match, subrepos): '''Get stat data about the files explicitly specified by match. @@ -757,18 +757,18 @@ directories and that were not found.''' def badtype(mode): - kind = _('unknown') + kind = _(b'unknown') if stat.S_ISCHR(mode): - kind = _('character device') + kind = _(b'character device') elif stat.S_ISBLK(mode): - kind = _('block device') + kind = _(b'block device') elif stat.S_ISFIFO(mode): - kind = _('fifo') + kind = _(b'fifo') elif stat.S_ISSOCK(mode): - kind = _('socket') + kind = _(b'socket') elif stat.S_ISDIR(mode): - kind = _('directory') - return _('unsupported file type (type is %s)') % kind + kind = _(b'directory') + return _(b'unsupported file type (type is %s)') % kind matchedir = match.explicitdir badfn = match.bad @@ -793,7 +793,7 @@ subrepos.sort() i, j = 0, 0 while i < len(files) and j < len(subrepos): - subpath = subrepos[j] + "/" + subpath = subrepos[j] + b"/" if files[i] < subpath: i += 1 continue @@ -801,13 +801,13 @@ del files[i] j += 1 - if not files or '' in files: - files = [''] + if not files or b'' in files: + files = [b''] # constructing the foldmap is expensive, so don't do it for the # common case where files is [''] normalize = None results = dict.fromkeys(subrepos) - results['.hg'] = None + results[b'.hg'] = None for ff in files: if normalize: @@ -849,7 +849,7 @@ # aren't filtered here because they will be tested later. if match.anypats(): for f in list(results): - if f == '.hg' or f in subrepos: + if f == b'.hg' or f in subrepos: # keep sentinel to disable further out-of-repo walks continue if not match(f): @@ -952,11 +952,11 @@ visitentries = match.visitchildrenset(nd) if not visitentries: continue - if visitentries == 'this' or visitentries == 'all': + if visitentries == b'this' or visitentries == b'all': visitentries = None skip = None - if nd != '': - skip = '.hg' + if nd != b'': + skip = b'.hg' try: entries = listdir(join(nd), stat=True, skip=skip) except OSError as inst: @@ -982,10 +982,10 @@ # interested in comparing it to files currently in the # dmap -- therefore normalizefile is enough nf = normalizefile( - nd and (nd + "/" + f) or f, True, True + nd and (nd + b"/" + f) or f, True, True ) else: - nf = nd and (nd + "/" + f) or f + nf = nd and (nd + b"/" + f) or f if nf not in results: if kind == dirkind: if not ignore(nf): @@ -1016,7 +1016,7 @@ for s in subrepos: del results[s] - del results['.hg'] + del results[b'.hg'] # step 3: visit remaining files from dmap if not skipstep3 and not exact: @@ -1134,9 +1134,9 @@ size = t[2] time = t[3] - if not st and state in "nma": + if not st and state in b"nma": dadd(fn) - elif state == 'n': + elif state == b'n': if ( size >= 0 and ( @@ -1160,11 +1160,11 @@ ladd(fn) elif listclean: cadd(fn) - elif state == 'm': + elif state == b'm': madd(fn) - elif state == 'a': + elif state == b'a': aadd(fn) - elif state == 'r': + elif state == b'r': radd(fn) return ( @@ -1208,7 +1208,7 @@ # output file will be used to create backup of dirstate at this point. if self._dirty or not self._opener.exists(filename): self._writedirstate( - self._opener(filename, "w", atomictemp=True, checkambig=True) + self._opener(filename, b"w", atomictemp=True, checkambig=True) ) if tr: @@ -1216,16 +1216,16 @@ # changes written out above, even if dirstate is never # changed after this tr.addfilegenerator( - 'dirstate', + b'dirstate', (self._filename,), self._writedirstate, - location='plain', + location=b'plain', ) # ensure that pending file written above is unlinked at # failure, even if tr.writepending isn't invoked until the # end of this transaction - tr.registertmp(filename, location='plain') + tr.registertmp(filename, location=b'plain') self._opener.tryunlink(backupname) # hardlink backup is okay because _writedirstate is always called @@ -1291,7 +1291,7 @@ self._ui = ui self._opener = opener self._root = root - self._filename = 'dirstate' + self._filename = b'dirstate' self._parents = None self._dirtyparents = False @@ -1315,12 +1315,12 @@ self._map.clear() self.copymap.clear() self.setparents(nullid, nullid) - util.clearcachedproperty(self, "_dirs") - util.clearcachedproperty(self, "_alldirs") - util.clearcachedproperty(self, "filefoldmap") - util.clearcachedproperty(self, "dirfoldmap") - util.clearcachedproperty(self, "nonnormalset") - util.clearcachedproperty(self, "otherparentset") + util.clearcachedproperty(self, b"_dirs") + util.clearcachedproperty(self, b"_alldirs") + util.clearcachedproperty(self, b"filefoldmap") + util.clearcachedproperty(self, b"dirfoldmap") + util.clearcachedproperty(self, b"nonnormalset") + util.clearcachedproperty(self, b"otherparentset") def items(self): return self._map.iteritems() @@ -1352,12 +1352,12 @@ def addfile(self, f, oldstate, state, mode, size, mtime): """Add a tracked file to the dirstate.""" - if oldstate in "?r" and r"_dirs" in self.__dict__: + if oldstate in b"?r" and r"_dirs" in self.__dict__: self._dirs.addpath(f) - if oldstate == "?" and r"_alldirs" in self.__dict__: + if oldstate == b"?" and r"_alldirs" in self.__dict__: self._alldirs.addpath(f) self._map[f] = dirstatetuple(state, mode, size, mtime) - if state != 'n' or mtime == -1: + if state != b'n' or mtime == -1: self.nonnormalset.add(f) if size == -2: self.otherparentset.add(f) @@ -1370,14 +1370,14 @@ the file's previous state. In the future, we should refactor this to be more explicit about what that state is. """ - if oldstate not in "?r" and r"_dirs" in self.__dict__: + if oldstate not in b"?r" and r"_dirs" in self.__dict__: self._dirs.delpath(f) - if oldstate == "?" and r"_alldirs" in self.__dict__: + if oldstate == b"?" and r"_alldirs" in self.__dict__: self._alldirs.addpath(f) if r"filefoldmap" in self.__dict__: normed = util.normcase(f) self.filefoldmap.pop(normed, None) - self._map[f] = dirstatetuple('r', 0, size, 0) + self._map[f] = dirstatetuple(b'r', 0, size, 0) self.nonnormalset.add(f) def dropfile(self, f, oldstate): @@ -1387,7 +1387,7 @@ """ exists = self._map.pop(f, None) is not None if exists: - if oldstate != "r" and r"_dirs" in self.__dict__: + if oldstate != b"r" and r"_dirs" in self.__dict__: self._dirs.delpath(f) if r"_alldirs" in self.__dict__: self._alldirs.delpath(f) @@ -1400,7 +1400,7 @@ def clearambiguoustimes(self, files, now): for f in files: e = self.get(f) - if e is not None and e[0] == 'n' and e[3] == now: + if e is not None and e[0] == b'n' and e[3] == now: self._map[f] = dirstatetuple(e[0], e[1], e[2], -1) self.nonnormalset.add(f) @@ -1412,9 +1412,9 @@ nonnorm = set() otherparent = set() for fname, e in self._map.iteritems(): - if e[0] != 'n' or e[3] == -1: + if e[0] != b'n' or e[3] == -1: nonnorm.add(fname) - if e[0] == 'n' and e[2] == -2: + if e[0] == b'n' and e[2] == -2: otherparent.add(fname) return nonnorm, otherparent @@ -1435,9 +1435,9 @@ f = {} normcase = util.normcase for name, s in self._map.iteritems(): - if s[0] != 'r': + if s[0] != b'r': f[normcase(name)] = name - f['.'] = '.' # prevents useless util.fspath() invocation + f[b'.'] = b'.' # prevents useless util.fspath() invocation return f def hastrackeddir(self, d): @@ -1456,7 +1456,7 @@ @propertycache def _dirs(self): - return util.dirs(self._map, 'r') + return util.dirs(self._map, b'r') @propertycache def _alldirs(self): @@ -1467,7 +1467,7 @@ if self._pendingmode is not None and self._pendingmode != mode: fp.close() raise error.Abort( - _('working directory state may be ' 'changed parallelly') + _(b'working directory state may be ' b'changed parallelly') ) self._pendingmode = mode return fp @@ -1482,7 +1482,7 @@ if err.errno != errno.ENOENT: raise # File doesn't exist, so the current state is empty - st = '' + st = b'' l = len(st) if l == 40: @@ -1491,7 +1491,7 @@ self._parents = (nullid, nullid) else: raise error.Abort( - _('working directory state appears ' 'damaged!') + _(b'working directory state appears ' b'damaged!') ) return self._parents @@ -1519,7 +1519,7 @@ if not st: return - if util.safehasattr(parsers, 'dict_new_presized'): + if util.safehasattr(parsers, b'dict_new_presized'): # Make an estimate of the number of files in the dirstate based on # its size. From a linear regression on a set of real-world repos, # all over 10,000 files, the size of a dirstate entry is 85 @@ -1595,7 +1595,7 @@ self._ui = ui self._opener = opener self._root = root - self._filename = 'dirstate' + self._filename = b'dirstate' self._parents = None self._dirtyparents = False @@ -1636,9 +1636,9 @@ def clear(self): self._rustmap.clear() self.setparents(nullid, nullid) - util.clearcachedproperty(self, "_dirs") - util.clearcachedproperty(self, "_alldirs") - util.clearcachedproperty(self, "dirfoldmap") + util.clearcachedproperty(self, b"_dirs") + util.clearcachedproperty(self, b"_alldirs") + util.clearcachedproperty(self, b"dirfoldmap") def items(self): return self._rustmap.items() @@ -1668,7 +1668,7 @@ if self._pendingmode is not None and self._pendingmode != mode: fp.close() raise error.Abort( - _('working directory state may be ' 'changed parallelly') + _(b'working directory state may be ' b'changed parallelly') ) self._pendingmode = mode return fp @@ -1688,13 +1688,13 @@ if err.errno != errno.ENOENT: raise # File doesn't exist, so the current state is empty - st = '' + st = b'' try: self._parents = self._rustmap.parents(st) except ValueError: raise error.Abort( - _('working directory state appears ' 'damaged!') + _(b'working directory state appears ' b'damaged!') ) return self._parents