def _dirs(self): return set(util.dirs(self._fileroots)) | set(['.'])
def __init__(self, root, cwd, patterns, include=[], exclude=[], default='glob', exact=False, auditor=None, ctx=None, listsubrepos=False, warn=None, badfn=None): """build an object to match a set of file patterns arguments: root - the canonical root of the tree you're matching against cwd - the current working directory, if relevant patterns - patterns to find include - patterns to include (unless they are excluded) exclude - patterns to exclude (even if they are included) default - if a pattern in patterns has no explicit type, assume this one exact - patterns are actually filenames (include/exclude still apply) warn - optional function used for printing warnings badfn - optional bad() callback for this matcher instead of the default a pattern is one of: 'glob:<glob>' - a glob relative to cwd 're:<regexp>' - a regular expression 'path:<path>' - a path relative to repository root 'relglob:<glob>' - an unrooted glob (*.c matches C files in all dirs) 'relpath:<path>' - a path relative to cwd 'relre:<regexp>' - a regexp that needn't match the start of a name 'set:<fileset>' - a fileset expression 'include:<path>' - a file of patterns to read and include 'subinclude:<path>' - a file of patterns to match against files under the same directory '<something>' - a pattern of the specified default type """ self._root = root self._cwd = cwd self._files = [] # exact files and roots of patterns self._anypats = bool(include or exclude) self._always = False self._pathrestricted = bool(include or exclude or patterns) self._warn = warn self._includeroots = set() self._includedirs = set(['.']) self._excluderoots = set() if badfn is not None: self.bad = badfn matchfns = [] if include: kindpats = self._normalize(include, 'glob', root, cwd, auditor) self.includepat, im = _buildmatch(ctx, kindpats, '(?:/|$)', listsubrepos, root) self._includeroots.update(_roots(kindpats)) self._includedirs.update(util.dirs(self._includeroots)) matchfns.append(im) if exclude: kindpats = self._normalize(exclude, 'glob', root, cwd, auditor) self.excludepat, em = _buildmatch(ctx, kindpats, '(?:/|$)', listsubrepos, root) if not _anypats(kindpats): self._excluderoots.update(_roots(kindpats)) matchfns.append(lambda f: not em(f)) if exact: if isinstance(patterns, list): self._files = patterns else: self._files = list(patterns) matchfns.append(self.exact) elif patterns: kindpats = self._normalize(patterns, default, root, cwd, auditor) if not _kindpatsalwaysmatch(kindpats): self._files = _roots(kindpats) self._anypats = self._anypats or _anypats(kindpats) self.patternspat, pm = _buildmatch(ctx, kindpats, '$', listsubrepos, root) matchfns.append(pm) if not matchfns: m = util.always self._always = True elif len(matchfns) == 1: m = matchfns[0] else: def m(f): for matchfn in matchfns: if not matchfn(f): return False return True self.matchfn = m self._fileroots = set(self._files)
def _dirs(self): return util.dirs(self._map, 'r')
def _walkexplicit(self, match, subrepos): '''Get stat data about the files explicitly specified by match. Return a triple (results, dirsfound, dirsnotfound). - results is a mapping from filename to stat result. It also contains listings mapping subrepos and .hg to None. - dirsfound is a list of files found to be directories. - dirsnotfound is a list of files that the dirstate thinks are directories and that were not found.''' 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 matchedir = match.explicitdir badfn = match.bad dmap = self._map lstat = os.lstat getkind = stat.S_IFMT dirkind = stat.S_IFDIR regkind = stat.S_IFREG lnkkind = stat.S_IFLNK join = self._join dirsfound = [] foundadd = dirsfound.append dirsnotfound = [] notfoundadd = dirsnotfound.append if not match.isexact() and self._checkcase: normalize = self._normalize else: normalize = None files = sorted(match.files()) subrepos.sort() i, j = 0, 0 while i < len(files) and j < len(subrepos): subpath = subrepos[j] + "/" if files[i] < subpath: i += 1 continue while i < len(files) and files[i].startswith(subpath): del files[i] j += 1 if not files or '.' in files: files = ['.'] results = dict.fromkeys(subrepos) results['.hg'] = None alldirs = None for ff in files: # constructing the foldmap is expensive, so don't do it for the # common case where files is ['.'] if normalize and ff != '.': nf = normalize(ff, False, True) else: nf = ff if nf in results: continue try: st = lstat(join(nf)) kind = getkind(st.st_mode) if kind == dirkind: if nf in dmap: # file replaced by dir on disk but still in dirstate results[nf] = None if matchedir: matchedir(nf) foundadd((nf, ff)) elif kind == regkind or kind == lnkkind: results[nf] = st else: badfn(ff, badtype(kind)) if nf in dmap: results[nf] = None except OSError as inst: # nf not found on disk - it is dirstate only if nf in dmap: # does it exactly match a missing file? results[nf] = None else: # does it match a missing directory? if alldirs is None: alldirs = util.dirs(dmap) if nf in alldirs: if matchedir: matchedir(nf) notfoundadd(nf) else: badfn(ff, inst.strerror) # Case insensitive filesystems cannot rely on lstat() failing to detect # a case-only rename. Prune the stat object for any file that does not # match the case in the filesystem, if there are multiple files that # normalize to the same path. if match.isexact() and self._checkcase: normed = {} for f, st in results.iteritems(): if st is None: continue nc = util.normcase(f) paths = normed.get(nc) if paths is None: paths = set() normed[nc] = paths paths.add(f) for norm, paths in normed.iteritems(): if len(paths) > 1: for path in paths: folded = self._discoverpath(path, norm, True, None, self._dirfoldmap) if path != folded: results[path] = None return results, dirsfound, dirsnotfound
def _walkexplicit(self, match, subrepos): '''Get stat data about the files explicitly specified by match. Return a triple (results, dirsfound, dirsnotfound). - results is a mapping from filename to stat result. It also contains listings mapping subrepos and .hg to None. - dirsfound is a list of files found to be directories. - dirsnotfound is a list of files that the dirstate thinks are directories and that were not found.''' 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 matchedir = match.explicitdir badfn = match.bad dmap = self._map lstat = os.lstat getkind = stat.S_IFMT dirkind = stat.S_IFDIR regkind = stat.S_IFREG lnkkind = stat.S_IFLNK join = self._join dirsfound = [] foundadd = dirsfound.append dirsnotfound = [] notfoundadd = dirsnotfound.append if not match.isexact() and self._checkcase: normalize = self._normalize else: normalize = None files = sorted(match.files()) subrepos.sort() i, j = 0, 0 while i < len(files) and j < len(subrepos): subpath = subrepos[j] + "/" if files[i] < subpath: i += 1 continue while i < len(files) and files[i].startswith(subpath): del files[i] j += 1 if not files or '.' in files: files = ['.'] results = dict.fromkeys(subrepos) results['.hg'] = None alldirs = None for ff in files: # constructing the foldmap is expensive, so don't do it for the # common case where files is ['.'] if normalize and ff != '.': nf = normalize(ff, False, True) else: nf = ff if nf in results: continue try: st = lstat(join(nf)) kind = getkind(st.st_mode) if kind == dirkind: if nf in dmap: # file replaced by dir on disk but still in dirstate results[nf] = None if matchedir: matchedir(nf) foundadd((nf, ff)) elif kind == regkind or kind == lnkkind: results[nf] = st else: badfn(ff, badtype(kind)) if nf in dmap: results[nf] = None except OSError, inst: # nf not found on disk - it is dirstate only if nf in dmap: # does it exactly match a missing file? results[nf] = None else: # does it match a missing directory? if alldirs is None: alldirs = util.dirs(dmap) if nf in alldirs: if matchedir: matchedir(nf) notfoundadd(nf) else: badfn(ff, inst.strerror)
def _dirs(self): return util.dirs(self)
def _alldirs(self): return util.dirs(self)
def _dirs(self): return set(util.dirs(self._fmap)) | set(['.'])