diff options
author | Ori Bernstein <ori@eigenstate.org> | 2021-06-14 00:00:37 +0000 |
---|---|---|
committer | Ori Bernstein <ori@eigenstate.org> | 2021-06-14 00:00:37 +0000 |
commit | a73a964e51247ed169d322c725a3a18859f109a3 (patch) | |
tree | 3f752d117274d444bda44e85609aeac1acf313f3 /sys/lib/python/mercurial/dirstate.py | |
parent | e64efe273fcb921a61bf27d33b230c4e64fcd425 (diff) |
python, hg: tow outside the environment.
they've served us well, and can ride off into the sunset.
Diffstat (limited to 'sys/lib/python/mercurial/dirstate.py')
-rw-r--r-- | sys/lib/python/mercurial/dirstate.py | 601 |
1 files changed, 0 insertions, 601 deletions
diff --git a/sys/lib/python/mercurial/dirstate.py b/sys/lib/python/mercurial/dirstate.py deleted file mode 100644 index c10e3a6c7..000000000 --- a/sys/lib/python/mercurial/dirstate.py +++ /dev/null @@ -1,601 +0,0 @@ -# dirstate.py - working directory tracking for mercurial -# -# Copyright 2005-2007 Matt Mackall <mpm@selenic.com> -# -# This software may be used and distributed according to the terms of the -# GNU General Public License version 2, incorporated herein by reference. - -from node import nullid -from i18n import _ -import util, ignore, osutil, parsers -import struct, os, stat, errno -import cStringIO, sys - -_unknown = ('?', 0, 0, 0) -_format = ">cllll" -propertycache = util.propertycache - -def _finddirs(path): - pos = path.rfind('/') - while pos != -1: - yield path[:pos] - pos = path.rfind('/', 0, pos) - -def _incdirs(dirs, path): - for base in _finddirs(path): - if base in dirs: - dirs[base] += 1 - return - dirs[base] = 1 - -def _decdirs(dirs, path): - for base in _finddirs(path): - if dirs[base] > 1: - dirs[base] -= 1 - return - del dirs[base] - -class dirstate(object): - - def __init__(self, opener, ui, root): - self._opener = opener - self._root = root - self._rootdir = os.path.join(root, '') - self._dirty = False - self._dirtypl = False - self._ui = ui - - @propertycache - def _map(self): - self._read() - return self._map - - @propertycache - def _copymap(self): - self._read() - return self._copymap - - @propertycache - def _foldmap(self): - f = {} - for name in self._map: - f[os.path.normcase(name)] = name - return f - - @propertycache - def _branch(self): - try: - return self._opener("branch").read().strip() or "default" - except IOError: - return "default" - - @propertycache - def _pl(self): - try: - st = self._opener("dirstate").read(40) - l = len(st) - if l == 40: - return st[:20], st[20:40] - elif l > 0 and l < 40: - raise util.Abort(_('working directory state appears damaged!')) - except IOError, err: - if err.errno != errno.ENOENT: raise - return [nullid, nullid] - - @propertycache - def _dirs(self): - dirs = {} - for f,s in self._map.iteritems(): - if s[0] != 'r': - _incdirs(dirs, f) - return dirs - - @propertycache - def _ignore(self): - files = [self._join('.hgignore')] - for name, path in self._ui.configitems("ui"): - if name == 'ignore' or name.startswith('ignore.'): - files.append(os.path.expanduser(path)) - return ignore.ignore(self._root, files, self._ui.warn) - - @propertycache - def _slash(self): - return self._ui.configbool('ui', 'slash') and os.sep != '/' - - @propertycache - def _checklink(self): - return util.checklink(self._root) - - @propertycache - def _checkexec(self): - return util.checkexec(self._root) - - @propertycache - def _checkcase(self): - return not util.checkcase(self._join('.hg')) - - def _join(self, f): - # much faster than os.path.join() - # it's safe because f is always a relative path - return self._rootdir + f - - def flagfunc(self, fallback): - if self._checklink: - if self._checkexec: - def f(x): - p = self._join(x) - if os.path.islink(p): - return 'l' - if util.is_exec(p): - return 'x' - return '' - return f - def f(x): - if os.path.islink(self._join(x)): - return 'l' - if 'x' in fallback(x): - return 'x' - return '' - return f - if self._checkexec: - def f(x): - if 'l' in fallback(x): - return 'l' - if util.is_exec(self._join(x)): - return 'x' - return '' - return f - return fallback - - def getcwd(self): - cwd = os.getcwd() - if cwd == self._root: return '' - # self._root ends with a path separator if self._root is '/' or 'C:\' - rootsep = self._root - if not util.endswithsep(rootsep): - rootsep += os.sep - if cwd.startswith(rootsep): - return cwd[len(rootsep):] - else: - # we're outside the repo. return an absolute path. - return cwd - - def pathto(self, f, cwd=None): - if cwd is None: - cwd = self.getcwd() - path = util.pathto(self._root, cwd, f) - if self._slash: - return util.normpath(path) - return path - - def __getitem__(self, key): - ''' current states: - n normal - m needs merging - r marked for removal - a marked for addition - ? not tracked''' - return self._map.get(key, ("?",))[0] - - def __contains__(self, key): - return key in self._map - - def __iter__(self): - for x in sorted(self._map): - yield x - - def parents(self): - return self._pl - - def branch(self): - return self._branch - - def setparents(self, p1, p2=nullid): - self._dirty = self._dirtypl = True - self._pl = p1, p2 - - def setbranch(self, branch): - self._branch = branch - self._opener("branch", "w").write(branch + '\n') - - def _read(self): - self._map = {} - self._copymap = {} - try: - st = self._opener("dirstate").read() - except IOError, err: - if err.errno != errno.ENOENT: raise - return - if not st: - return - - p = parsers.parse_dirstate(self._map, self._copymap, st) - if not self._dirtypl: - self._pl = p - - def invalidate(self): - for a in "_map _copymap _foldmap _branch _pl _dirs _ignore".split(): - if a in self.__dict__: - delattr(self, a) - self._dirty = False - - def copy(self, source, dest): - """Mark dest as a copy of source. Unmark dest if source is None. - """ - if source == dest: - return - self._dirty = True - if source is not None: - self._copymap[dest] = source - elif dest in self._copymap: - del self._copymap[dest] - - def copied(self, file): - return self._copymap.get(file, None) - - def copies(self): - return self._copymap - - def _droppath(self, f): - if self[f] not in "?r" and "_dirs" in self.__dict__: - _decdirs(self._dirs, f) - - def _addpath(self, f, check=False): - oldstate = self[f] - if check or oldstate == "r": - if '\r' in f or '\n' in f: - raise util.Abort( - _("'\\n' and '\\r' disallowed in filenames: %r") % f) - if f in self._dirs: - raise util.Abort(_('directory %r already in dirstate') % f) - # shadows - for d in _finddirs(f): - if d in self._dirs: - break - if d in self._map and self[d] != 'r': - raise util.Abort( - _('file %r in dirstate clashes with %r') % (d, f)) - if oldstate in "?r" and "_dirs" in self.__dict__: - _incdirs(self._dirs, f) - - def normal(self, f): - 'mark a file normal and clean' - self._dirty = True - self._addpath(f) - s = os.lstat(self._join(f)) - self._map[f] = ('n', s.st_mode, s.st_size, int(s.st_mtime)) - if f in self._copymap: - del self._copymap[f] - - def normallookup(self, f): - 'mark a file normal, but possibly dirty' - if self._pl[1] != nullid and f in self._map: - # if there is a merge going on and the file was either - # in state 'm' or dirty before being removed, restore that state. - entry = self._map[f] - if entry[0] == 'r' and entry[2] in (-1, -2): - source = self._copymap.get(f) - if entry[2] == -1: - self.merge(f) - elif entry[2] == -2: - self.normaldirty(f) - if source: - self.copy(source, f) - return - if entry[0] == 'm' or entry[0] == 'n' and entry[2] == -2: - return - self._dirty = True - self._addpath(f) - self._map[f] = ('n', 0, -1, -1) - if f in self._copymap: - del self._copymap[f] - - def normaldirty(self, f): - 'mark a file normal, but dirty' - self._dirty = True - self._addpath(f) - self._map[f] = ('n', 0, -2, -1) - if f in self._copymap: - del self._copymap[f] - - def add(self, f): - 'mark a file added' - self._dirty = True - self._addpath(f, True) - self._map[f] = ('a', 0, -1, -1) - if f in self._copymap: - del self._copymap[f] - - def remove(self, f): - 'mark a file removed' - self._dirty = True - self._droppath(f) - size = 0 - if self._pl[1] != nullid and f in self._map: - entry = self._map[f] - if entry[0] == 'm': - size = -1 - elif entry[0] == 'n' and entry[2] == -2: - size = -2 - self._map[f] = ('r', 0, size, 0) - if size == 0 and f in self._copymap: - del self._copymap[f] - - def merge(self, f): - 'mark a file merged' - self._dirty = True - s = os.lstat(self._join(f)) - self._addpath(f) - self._map[f] = ('m', s.st_mode, s.st_size, int(s.st_mtime)) - if f in self._copymap: - del self._copymap[f] - - def forget(self, f): - 'forget a file' - self._dirty = True - try: - self._droppath(f) - del self._map[f] - except KeyError: - self._ui.warn(_("not in dirstate: %s\n") % f) - - def _normalize(self, path, knownpath): - norm_path = os.path.normcase(path) - fold_path = self._foldmap.get(norm_path, None) - if fold_path is None: - if knownpath or not os.path.exists(os.path.join(self._root, path)): - fold_path = path - else: - fold_path = self._foldmap.setdefault(norm_path, - util.fspath(path, self._root)) - return fold_path - - def clear(self): - self._map = {} - if "_dirs" in self.__dict__: - delattr(self, "_dirs"); - self._copymap = {} - self._pl = [nullid, nullid] - self._dirty = True - - def rebuild(self, parent, files): - self.clear() - for f in files: - if 'x' in files.flags(f): - self._map[f] = ('n', 0777, -1, 0) - else: - self._map[f] = ('n', 0666, -1, 0) - self._pl = (parent, nullid) - self._dirty = True - - def write(self): - if not self._dirty: - return - st = self._opener("dirstate", "w", atomictemp=True) - - try: - gran = int(self._ui.config('dirstate', 'granularity', 1)) - except ValueError: - gran = 1 - limit = sys.maxint - if gran > 0: - limit = util.fstat(st).st_mtime - gran - - cs = cStringIO.StringIO() - copymap = self._copymap - pack = struct.pack - write = cs.write - write("".join(self._pl)) - for f, e in self._map.iteritems(): - if f in copymap: - f = "%s\0%s" % (f, copymap[f]) - if e[3] > limit and e[0] == 'n': - e = (e[0], 0, -1, -1) - e = pack(_format, e[0], e[1], e[2], e[3], len(f)) - write(e) - write(f) - st.write(cs.getvalue()) - st.rename() - self._dirty = self._dirtypl = False - - def _dirignore(self, f): - if f == '.': - return False - if self._ignore(f): - return True - for p in _finddirs(f): - if self._ignore(p): - return True - return False - - def walk(self, match, unknown, ignored): - ''' - walk recursively through the directory tree, finding all files - matched by the match function - - results are yielded in a tuple (filename, stat), where stat - and st is the stat result if the file was found in the directory. - ''' - - def fwarn(f, msg): - self._ui.warn('%s: %s\n' % (self.pathto(f), msg)) - return False - - def badtype(mode): - kind = _('unknown') - if stat.S_ISCHR(mode): kind = _('character device') - elif stat.S_ISBLK(mode): kind = _('block device') - elif stat.S_ISFIFO(mode): kind = _('fifo') - elif stat.S_ISSOCK(mode): kind = _('socket') - elif stat.S_ISDIR(mode): kind = _('directory') - return _('unsupported file type (type is %s)') % kind - - ignore = self._ignore - dirignore = self._dirignore - if ignored: - ignore = util.never - dirignore = util.never - elif not unknown: - # if unknown and ignored are False, skip step 2 - ignore = util.always - dirignore = util.always - - matchfn = match.matchfn - badfn = match.bad - dmap = self._map - normpath = util.normpath - listdir = osutil.listdir - lstat = os.lstat - getkind = stat.S_IFMT - dirkind = stat.S_IFDIR - regkind = stat.S_IFREG - lnkkind = stat.S_IFLNK - join = self._join - work = [] - wadd = work.append - - if self._checkcase: - normalize = self._normalize - else: - normalize = lambda x, y: x - - exact = skipstep3 = False - if matchfn == match.exact: # match.exact - exact = True - dirignore = util.always # skip step 2 - elif match.files() and not match.anypats(): # match.match, no patterns - skipstep3 = True - - files = set(match.files()) - if not files or '.' in files: - files = [''] - results = {'.hg': None} - - # step 1: find all explicit files - for ff in sorted(files): - nf = normalize(normpath(ff), False) - if nf in results: - continue - - try: - st = lstat(join(nf)) - kind = getkind(st.st_mode) - if kind == dirkind: - skipstep3 = False - if nf in dmap: - #file deleted on disk but still in dirstate - results[nf] = None - match.dir(nf) - if not dirignore(nf): - wadd(nf) - elif kind == regkind or kind == lnkkind: - results[nf] = st - else: - badfn(ff, badtype(kind)) - if nf in dmap: - results[nf] = None - except OSError, inst: - if nf in dmap: # does it exactly match a file? - results[nf] = None - else: # does it match a directory? - prefix = nf + "/" - for fn in dmap: - if fn.startswith(prefix): - match.dir(nf) - skipstep3 = False - break - else: - badfn(ff, inst.strerror) - - # step 2: visit subdirectories - while work: - nd = work.pop() - skip = None - if nd == '.': - nd = '' - else: - skip = '.hg' - try: - entries = listdir(join(nd), stat=True, skip=skip) - except OSError, inst: - if inst.errno == errno.EACCES: - fwarn(nd, inst.strerror) - continue - raise - for f, kind, st in entries: - nf = normalize(nd and (nd + "/" + f) or f, True) - if nf not in results: - if kind == dirkind: - if not ignore(nf): - match.dir(nf) - wadd(nf) - if nf in dmap and matchfn(nf): - results[nf] = None - elif kind == regkind or kind == lnkkind: - if nf in dmap: - if matchfn(nf): - results[nf] = st - elif matchfn(nf) and not ignore(nf): - results[nf] = st - elif nf in dmap and matchfn(nf): - results[nf] = None - - # step 3: report unseen items in the dmap hash - if not skipstep3 and not exact: - visit = sorted([f for f in dmap if f not in results and matchfn(f)]) - for nf, st in zip(visit, util.statfiles([join(i) for i in visit])): - if not st is None and not getkind(st.st_mode) in (regkind, lnkkind): - st = None - results[nf] = st - - del results['.hg'] - return results - - def status(self, match, ignored, clean, unknown): - listignored, listclean, listunknown = ignored, clean, unknown - lookup, modified, added, unknown, ignored = [], [], [], [], [] - removed, deleted, clean = [], [], [] - - dmap = self._map - ladd = lookup.append - madd = modified.append - aadd = added.append - uadd = unknown.append - iadd = ignored.append - radd = removed.append - dadd = deleted.append - cadd = clean.append - - for fn, st in self.walk(match, listunknown, listignored).iteritems(): - if fn not in dmap: - if (listignored or match.exact(fn)) and self._dirignore(fn): - if listignored: - iadd(fn) - elif listunknown: - uadd(fn) - continue - - state, mode, size, time = dmap[fn] - - if not st and state in "nma": - dadd(fn) - elif state == 'n': - if (size >= 0 and - (size != st.st_size - or ((mode ^ st.st_mode) & 0100 and self._checkexec)) - or size == -2 - or fn in self._copymap): - madd(fn) - elif time != int(st.st_mtime): - ladd(fn) - elif listclean: - cadd(fn) - elif state == 'm': - madd(fn) - elif state == 'a': - aadd(fn) - elif state == 'r': - radd(fn) - - return (lookup, modified, added, removed, deleted, unknown, ignored, - clean) |