diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py --- a/mercurial/dirstate.py +++ b/mercurial/dirstate.py @@ -127,8 +127,7 @@ @propertycache def _map(self): - '''Return the dirstate contents as a map from filename to - (state, mode, size, time).''' + '''Returns the dirstate map.''' self._map = dirstatemap(self._ui, self._opener, self._root) return self._map @@ -416,11 +415,11 @@ self._map.dirs.addpath(f) self._dirty = True self._updatedfiles.add(f) - self._map[f] = dirstatetuple(state, mode, size, mtime) if state != 'n' or mtime == -1: self._map.nonnormalset.add(f) if size == -2: self._map.otherparentset.add(f) + self._map.addfile(f, state, mode, size, mtime) def normal(self, f): '''Mark a file normal and clean.''' @@ -491,8 +490,8 @@ elif entry[0] == 'n' and entry[2] == -2: # other parent size = -2 self._map.otherparentset.add(f) - self._map[f] = dirstatetuple('r', 0, size, 0) self._map.nonnormalset.add(f) + self._map.removefile(f, size) if size == 0: self._map.copymap.pop(f, None) @@ -504,10 +503,9 @@ def drop(self, f): '''Drop a file from the dirstate''' - if f in self._map: + if self._map.dropfile(f): self._dirty = True self._droppath(f) - del self._map[f] if f in self._map.nonnormalset: self._map.nonnormalset.remove(f) self._map.copymap.pop(f, None) @@ -637,7 +635,7 @@ for f in self._updatedfiles: e = dmap.get(f) if e is not None and e[0] == 'n' and e[3] == now: - dmap[f] = dirstatetuple(e[0], e[1], e[2], -1) + dmap.addfile(f, e[0], e[1], e[2], -1) self._map.nonnormalset.add(f) # emulate that all 'dirstate.normal' results are written out @@ -1245,15 +1243,9 @@ def __contains__(self, key): return key in self._map - def __setitem__(self, key, value): - self._map[key] = value - def __getitem__(self, key): return self._map[key] - def __delitem__(self, key): - del self._map[key] - def keys(self): return self._map.keys() @@ -1261,6 +1253,30 @@ """Loads the underlying data, if it's not already loaded""" self._map + def addfile(self, f, state, mode, size, mtime): + """Add a tracked file to the dirstate.""" + self._map[f] = dirstatetuple(state, mode, size, mtime) + + def removefile(self, f, size): + """ + Mark a file as removed in the dirstate. + + The `size` parameter is used to store sentinel values that indicate + the file's previous state. In the future, we should refactor this + to be more explicit about what that state is. + """ + self._map[f] = dirstatetuple('r', 0, size, 0) + + def dropfile(self, f): + """ + Remove a file from the dirstate. Returns True if the file was + previously recorded. + """ + exists = f in self._map + if exists: + del self._map[f] + return exists + def nonnormalentries(self): '''Compute the nonnormal dirstate entries from the dmap''' try: @@ -1390,8 +1406,6 @@ # Avoid excess attribute lookups by fast pathing certain checks self.__contains__ = self._map.__contains__ self.__getitem__ = self._map.__getitem__ - self.__setitem__ = self._map.__setitem__ - self.__delitem__ = self._map.__delitem__ self.get = self._map.get def write(self, st, now):