def _checkcollision(mctx, wctx): "check for case folding collisions in the destination context" folded = {} for fn in mctx: fold = util.normcase(fn) if fold in folded: raise util.Abort( _("case-folding collision between %s and %s") % (fn, folded[fold])) folded[fold] = fn if wctx: # class to delay looking up copy mapping class pathcopies(object): @util.propertycache def map(self): # {dst@mctx: src@wctx} copy mapping return copies.pathcopies(wctx, mctx) pc = pathcopies() for fn in wctx: fold = util.normcase(fn) mfn = folded.get(fold, None) if mfn and mfn != fn and pc.map.get(mfn) != fn: raise util.Abort( _("case-folding collision between %s and %s") % (mfn, fn))
def _foldmap(self): f = {} for name in self._map: f[util.normcase(name)] = name for name in self._dirs: f[util.normcase(name)] = name f['.'] = '.' # prevents useless util.fspath() invocation return f
def _foldmap(self): f = {} for name, s in self._map.iteritems(): if s[0] != 'r': f[util.normcase(name)] = name for name in self._dirs: f[util.normcase(name)] = name f['.'] = '.' # prevents useless util.fspath() invocation return f
def _normalize(self, path, isknown, ignoremissing=False, exists=None): normed = util.normcase(path) folded = self._foldmap.get(normed, None) if folded is None: if isknown: folded = path else: if exists is None: 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) d = self._normalize(d, isknown, ignoremissing, None) folded = d + "/" + 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) d = self._normalize(d, isknown, ignoremissing, True) r = self._root + "/" + d folded = d + "/" + util.fspath(f, r) else: folded = util.fspath(normed, self._root) self._foldmap[normed] = folded return folded
def _checkcollision(repo, wmf, actions): # build provisional merged manifest up pmmf = set(wmf) if actions: # k, dr, e and rd are no-op for m in 'a', 'f', 'g', 'cd', 'dc': for f, args, msg in actions[m]: pmmf.add(f) for f, args, msg in actions['r']: pmmf.discard(f) for f, args, msg in actions['dm']: f2, flags = args pmmf.discard(f2) pmmf.add(f) for f, args, msg in actions['dg']: pmmf.add(f) for f, args, msg in actions['m']: f1, f2, fa, move, anc = args if move: pmmf.discard(f1) pmmf.add(f) # check case-folding collision in provisional merged manifest foldmap = {} for f in sorted(pmmf): fold = util.normcase(f) if fold in foldmap: raise util.Abort(_("case-folding collision between %s and %s") % (f, foldmap[fold])) foldmap[fold] = f
def _checkcollision(repo, wmf, actions): # build provisional merged manifest up pmmf = set(wmf) if actions: # k, dr, e and rd are no-op for m in 'a', 'f', 'g', 'cd', 'dc': for f, args, msg in actions[m]: pmmf.add(f) for f, args, msg in actions['r']: pmmf.discard(f) for f, args, msg in actions['dm']: f2, flags = args pmmf.discard(f2) pmmf.add(f) for f, args, msg in actions['dg']: f2, flags = args pmmf.add(f) for f, args, msg in actions['m']: f1, f2, fa, move, anc = args if move: pmmf.discard(f1) pmmf.add(f) # check case-folding collision in provisional merged manifest foldmap = {} for f in sorted(pmmf): fold = util.normcase(f) if fold in foldmap: raise util.Abort( _("case-folding collision between %s and %s") % (f, foldmap[fold])) foldmap[fold] = f
def _checkcollision(repo, wmf, actions, prompts): # build provisional merged manifest up pmmf = set(wmf) def addop(f, args): pmmf.add(f) def removeop(f, args): pmmf.discard(f) def nop(f, args): pass def renameop(f, args): f2, fd, flags = args if f: pmmf.discard(f) pmmf.add(fd) def mergeop(f, args): f2, fd, move = args if move: pmmf.discard(f) pmmf.add(fd) opmap = { "a": addop, "d": renameop, "dr": nop, "e": nop, "f": addop, # untracked file should be kept in working directory "g": addop, "m": mergeop, "r": removeop, "rd": nop, } for f, m, args, msg in actions: op = opmap.get(m) assert op, m op(f, args) opmap = { "cd": addop, "dc": addop, } for f, m in prompts: op = opmap.get(m) assert op, m op(f, None) # check case-folding collision in provisional merged manifest foldmap = {} for f in sorted(pmmf): fold = util.normcase(f) if fold in foldmap: raise util.Abort( _("case-folding collision between %s and %s") % (f, foldmap[fold])) foldmap[fold] = f
def _droppath(self, f): if self[f] not in "?r" and "_dirs" in self.__dict__: self._dirs.delpath(f) if "_filefoldmap" in self.__dict__: normed = util.normcase(f) if normed in self._filefoldmap: del self._filefoldmap[normed]
def _checkcollision(mctx, wctx): "check for case folding collisions in the destination context" folded = {} for fn in mctx: fold = util.normcase(fn) if fold in folded: raise util.Abort(_("case-folding collision between %s and %s") % (fn, folded[fold])) folded[fold] = fn if wctx: for fn in wctx: fold = util.normcase(fn) mfn = folded.get(fold, None) if mfn and (mfn != fn): raise util.Abort(_("case-folding collision between %s and %s") % (mfn, fn))
def _checkcollision(mctx, wctx): "check for case folding collisions in the destination context" folded = {} for fn in mctx: fold = util.normcase(fn) if fold in folded: raise util.Abort( _("case-folding collision between %s and %s") % (fn, folded[fold])) folded[fold] = fn if wctx: for fn in wctx: fold = util.normcase(fn) mfn = folded.get(fold, None) if mfn and (mfn != fn): raise util.Abort( _("case-folding collision between %s and %s") % (mfn, fn))
def _normalize(self, path, isknown): normed = util.normcase(path) folded = self._foldmap.get(normed, None) if folded is None: if isknown or not os.path.lexists(os.path.join(self._root, path)): folded = path else: folded = self._foldmap.setdefault(normed, util.fspath(normed, self._normroot)) return folded
def _normalizefile(self, path, isknown, ignoremissing=False, exists=None): normed = util.normcase(path) folded = self._filefoldmap.get(normed, None) if folded is None: if isknown: folded = path else: folded = self._discoverpath(path, normed, ignoremissing, exists, self._filefoldmap) return folded
def _checkcollision(repo, wmf, actions, prompts): # build provisional merged manifest up pmmf = set(wmf) def addop(f, args): pmmf.add(f) def removeop(f, args): pmmf.discard(f) def nop(f, args): pass def renameop(f, args): f2, fd, flags = args if f: pmmf.discard(f) pmmf.add(fd) def mergeop(f, args): f2, fd, move = args if move: pmmf.discard(f) pmmf.add(fd) opmap = { "a": addop, "d": renameop, "dr": nop, "e": nop, "f": addop, # untracked file should be kept in working directory "g": addop, "m": mergeop, "r": removeop, "rd": nop, } for f, m, args, msg in actions: op = opmap.get(m) assert op, m op(f, args) opmap = { "cd": addop, "dc": addop, } for f, m in prompts: op = opmap.get(m) assert op, m op(f, None) # check case-folding collision in provisional merged manifest foldmap = {} for f in sorted(pmmf): fold = util.normcase(f) if fold in foldmap: raise util.Abort(_("case-folding collision between %s and %s") % (f, foldmap[fold])) foldmap[fold] = f
def _normalize(self, path, isknown, ignoremissing=False, exists=None): normed = util.normcase(path) folded = self._filefoldmap.get(normed, None) if folded is None: folded = self._dirfoldmap.get(normed, None) if folded is None: if isknown: folded = path else: # store discovered result in dirfoldmap so that future # normalizefile calls don't start matching directories folded = self._discoverpath(path, normed, ignoremissing, exists, self._dirfoldmap) return folded
def _checkcollision(mctx, wctx): "check for case folding collisions in the destination context" folded = {} for fn in mctx: fold = util.normcase(fn) if fold in folded: raise util.Abort(_("case-folding collision between %s and %s") % (fn, folded[fold])) folded[fold] = fn if wctx: # class to delay looking up copy mapping class pathcopies(object): @util.propertycache def map(self): # {dst@mctx: src@wctx} copy mapping return copies.pathcopies(wctx, mctx) pc = pathcopies() for fn in wctx: fold = util.normcase(fn) mfn = folded.get(fold, None) if mfn and mfn != fn and pc.map.get(mfn) != fn: raise util.Abort(_("case-folding collision between %s and %s") % (mfn, fn))
def _normalize(self, path, isknown): normed = util.normcase(path) folded = self._foldmap.get(normed, None) if folded is None: if isknown or not os.path.lexists(os.path.join(self._root, path)): folded = path else: # recursively normalize leading directory components # against dirstate if '/' in normed: d, f = normed.rsplit('/', 1) d = self._normalize(d, isknown) r = self._root + "/" + d folded = d + "/" + util.fspath(f, r) else: folded = util.fspath(normed, self._root) self._foldmap[normed] = folded return folded
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 _normroot(self): return util.normcase(self._root)