Patchwork [3,of,6,V7] dirstate: add code to update the non-normal set

login
register
mail settings
Submitter Laurent Charignon
Date Dec. 23, 2015, 9:20 p.m.
Message ID <dc11fff375efd02043a4.1450905618@mbuchanan-mbp.DHCP.thefacebook.com>
Download mbox | patch
Permalink /patch/12326/
State Accepted
Headers show

Comments

Laurent Charignon - Dec. 23, 2015, 9:20 p.m.
# HG changeset patch
# User Laurent Charignon <lcharignon@fb.com>
# Date 1450905523 28800
#      Wed Dec 23 13:18:43 2015 -0800
# Node ID dc11fff375efd02043a4f5e7ccce678a13c76b82
# Parent  4627531d1b9a28aae2b610bfa40d03f2dfda3e96
dirstate: add code to update the non-normal set

Before this patch, we were only populating the non-normal set when parsing
or packing the dirstate. This was not enough to keep the non-normal set up to
date at all time as we don't write and read the dirstate whenever a change
happens. This patch solves this issue by updating the non-normal set when it
should be updated. note: pack_dirstate changes the dmap and we have it keep
it unchanged for retrocompatibility so we are forced to recompute the
non-normal set after calling it.

Patch

diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py
--- a/mercurial/dirstate.py
+++ b/mercurial/dirstate.py
@@ -427,7 +427,7 @@  class dirstate(object):
 
     def invalidate(self):
         for a in ("_map", "_copymap", "_filefoldmap", "_dirfoldmap", "_branch",
-                  "_pl", "_dirs", "_ignore"):
+                  "_pl", "_dirs", "_ignore", "_nonnormalset"):
             if a in self.__dict__:
                 delattr(self, a)
         self._lastnormaltime = 0
@@ -476,6 +476,8 @@  class dirstate(object):
             self._dirs.addpath(f)
         self._dirty = True
         self._map[f] = dirstatetuple(state, mode, size, mtime)
+        if state != 'n' or mtime == -1:
+            self._nonnormalset.add(f)
 
     def normal(self, f):
         '''Mark a file normal and clean.'''
@@ -485,6 +487,8 @@  class dirstate(object):
                       s.st_size & _rangemask, mtime & _rangemask)
         if f in self._copymap:
             del self._copymap[f]
+        if f in self._nonnormalset:
+            self._nonnormalset.remove(f)
         if mtime > self._lastnormaltime:
             # Remember the most recent modification timeslot for status(),
             # to make sure we won't miss future size-preserving file content
@@ -512,6 +516,8 @@  class dirstate(object):
         self._addpath(f, 'n', 0, -1, -1)
         if f in self._copymap:
             del self._copymap[f]
+        if f in self._nonnormalset:
+            self._nonnormalset.remove(f)
 
     def otherparent(self, f):
         '''Mark as coming from the other parent, always dirty.'''
@@ -547,6 +553,7 @@  class dirstate(object):
             elif entry[0] == 'n' and entry[2] == -2: # other parent
                 size = -2
         self._map[f] = dirstatetuple('r', 0, size, 0)
+        self._nonnormalset.add(f)
         if size == 0 and f in self._copymap:
             del self._copymap[f]
 
@@ -562,6 +569,8 @@  class dirstate(object):
             self._dirty = True
             self._droppath(f)
             del self._map[f]
+            if f in self._nonnormalset:
+                self._nonnormalset.remove(f)
 
     def _discoverpath(self, path, normed, ignoremissing, exists, storemap):
         if exists is None:
@@ -639,6 +648,7 @@  class dirstate(object):
 
     def clear(self):
         self._map = {}
+        self._nonnormalset = set()
         if "_dirs" in self.__dict__:
             delattr(self, "_dirs")
         self._copymap = {}
@@ -663,6 +673,8 @@  class dirstate(object):
                 self._map[f] = dirstatetuple('n', mode, -1, 0)
             else:
                 self._map.pop(f, None)
+                if f in self._nonnormalset:
+                    self._nonnormalset.remove(f)
 
         self._pl = (parent, nullid)
         self._dirty = True
@@ -696,6 +708,7 @@  class dirstate(object):
             for f, e in dmap.iteritems():
                 if e[0] == 'n' and e[3] == now:
                     dmap[f] = dirstatetuple(e[0], e[1], e[2], -1)
+                    self._nonnormalset.add(f)
 
             # emulate that all 'dirstate.normal' results are written out
             self._lastnormaltime = 0
@@ -730,6 +743,7 @@  class dirstate(object):
                     break
 
         st.write(parsers.pack_dirstate(self._map, self._copymap, self._pl, now))
+        self._nonnormalset = nonnomalentries(self._map)
         st.close()
         self._lastnormaltime = 0
         self._dirty = self._dirtypl = False