# fn may have just been marked as normal and it may have # changed in the same second without changing its size. # This can happen if we quickly do multiple commits. # Force lookup, so we don't miss such a racy file change. ladd(fn) elif listclean: cadd(fn) elif state == 'm': madd(fn) elif state == 'a': aadd(fn) elif state == 'r': radd(fn) return (lookup, scmutil.status(modified, added, removed, deleted, unknown, ignored, clean)) def matches(self, match): ''' return files in the dirstate (in whatever state) filtered by match ''' dmap = self._map if match.always(): return dmap.keys() files = match.files() if match.matchfn == match.exact: # fast path -- filter the other way around, since typically files is # much smaller than dmap return [f for f in files if f in dmap] if not match.anypats() and util.all(fn in dmap for fn in files): # fast path -- all the values are known to be files, so just return
def status(self, match, subrepos, ignored, clean, unknown): '''Determine the status of the working copy relative to the dirstate and return a pair of (unsure, status), where status is of type scmutil.status and: unsure: files that might have been modified since the dirstate was written, but need to be read to be sure (size is the same but mtime differs) status.modified: files that have definitely been modified since the dirstate was written (different size or mode) status.clean: files that have definitely not been modified since the dirstate was written ''' listignored, listclean, listunknown = ignored, clean, unknown lookup, modified, added, unknown, ignored = [], [], [], [], [] removed, deleted, clean = [], [], [] dmap = self._map ladd = lookup.append # aka "unsure" madd = modified.append aadd = added.append uadd = unknown.append iadd = ignored.append radd = removed.append dadd = deleted.append cadd = clean.append mexact = match.exact dirignore = self._dirignore checkexec = self._checkexec copymap = self._copymap lastnormaltime = self._lastnormaltime # We need to do full walks when either # - we're listing all clean files, or # - match.traversedir does something, because match.traversedir should # be called for every dir in the working dir full = listclean or match.traversedir is not None for fn, st in self.walk(match, subrepos, listunknown, listignored, full=full).iteritems(): if fn not in dmap: if (listignored or mexact(fn)) and dirignore(fn): if listignored: iadd(fn) else: uadd(fn) continue # This is equivalent to 'state, mode, size, time = dmap[fn]' but not # written like that for performance reasons. dmap[fn] is not a # Python tuple in compiled builds. The CPython UNPACK_SEQUENCE # opcode has fast paths when the value to be unpacked is a tuple or # a list, but falls back to creating a full-fledged iterator in # general. That is much slower than simply accessing and storing the # tuple members one by one. t = dmap[fn] state = t[0] mode = t[1] size = t[2] time = t[3] if not st and state in "nma": dadd(fn) elif state == 'n': mtime = util.statmtimesec(st) if (size >= 0 and ( (size != st.st_size and size != st.st_size & _rangemask) or ((mode ^ st.st_mode) & 0o100 and checkexec)) or size == -2 # other parent or fn in copymap): madd(fn) elif time != mtime and time != mtime & _rangemask: ladd(fn) elif mtime == lastnormaltime: # fn may have just been marked as normal and it may have # changed in the same second without changing its size. # This can happen if we quickly do multiple commits. # Force lookup, so we don't miss such a racy file change. ladd(fn) elif listclean: cadd(fn) elif state == 'm': madd(fn) elif state == 'a': aadd(fn) elif state == 'r': radd(fn) return (lookup, scmutil.status(modified, added, removed, deleted, unknown, ignored, clean))
elif mtime == lastnormaltime: # fn may have been changed in the same timeslot without # changing its size. This can happen if we quickly do # multiple commits in a single transaction. # Force lookup, so we don't miss such a racy file change. ladd(fn) elif listclean: cadd(fn) elif state == 'm': madd(fn) elif state == 'a': aadd(fn) elif state == 'r': radd(fn) return (lookup, scmutil.status(modified, added, removed, deleted, unknown, ignored, clean)) def matches(self, match): ''' return files in the dirstate (in whatever state) filtered by match ''' dmap = self._map if match.always(): return dmap.keys() files = match.files() if match.matchfn == match.exact: # fast path -- filter the other way around, since typically files is # much smaller than dmap return [f for f in files if f in dmap] if not match.anypats() and util.all(fn in dmap for fn in files): # fast path -- all the values are known to be files, so just return
def status(self, match, subrepos, ignored, clean, unknown): '''Determine the status of the working copy relative to the dirstate and return a pair of (unsure, status), where status is of type scmutil.status and: unsure: files that might have been modified since the dirstate was written, but need to be read to be sure (size is the same but mtime differs) status.modified: files that have definitely been modified since the dirstate was written (different size or mode) status.clean: files that have definitely not been modified since the dirstate was written ''' listignored, listclean, listunknown = ignored, clean, unknown lookup, modified, added, unknown, ignored = [], [], [], [], [] removed, deleted, clean = [], [], [] dmap = self._map ladd = lookup.append # aka "unsure" madd = modified.append aadd = added.append uadd = unknown.append iadd = ignored.append radd = removed.append dadd = deleted.append cadd = clean.append mexact = match.exact dirignore = self._dirignore checkexec = self._checkexec copymap = self._copymap lastnormaltime = self._lastnormaltime # We need to do full walks when either # - we're listing all clean files, or # - match.traversedir does something, because match.traversedir should # be called for every dir in the working dir full = listclean or match.traversedir is not None for fn, st in self.walk(match, subrepos, listunknown, listignored, full=full).iteritems(): if fn not in dmap: if (listignored or mexact(fn)) and dirignore(fn): if listignored: iadd(fn) else: uadd(fn) continue # This is equivalent to 'state, mode, size, time = dmap[fn]' but not # written like that for performance reasons. dmap[fn] is not a # Python tuple in compiled builds. The CPython UNPACK_SEQUENCE # opcode has fast paths when the value to be unpacked is a tuple or # a list, but falls back to creating a full-fledged iterator in # general. That is much slower than simply accessing and storing the # tuple members one by one. t = dmap[fn] state = t[0] mode = t[1] size = t[2] time = t[3] if not st and state in "nma": dadd(fn) elif state == 'n': mtime = int(st.st_mtime) if (size >= 0 and ((size != st.st_size and size != st.st_size & _rangemask) or ((mode ^ st.st_mode) & 0o100 and checkexec)) or size == -2 # other parent or fn in copymap): madd(fn) elif time != mtime and time != mtime & _rangemask: ladd(fn) elif mtime == lastnormaltime: # fn may have just been marked as normal and it may have # changed in the same second without changing its size. # This can happen if we quickly do multiple commits. # Force lookup, so we don't miss such a racy file change. ladd(fn) elif listclean: cadd(fn) elif state == 'm': madd(fn) elif state == 'a': aadd(fn) elif state == 'r': radd(fn) return (lookup, scmutil.status(modified, added, removed, deleted, unknown, ignored, clean))