[PATCH 4 of 5 V2] dirstate: change debugrebuilddirstate --minimal to use dirstate.rebuild

cdelahousse at fb.com cdelahousse at fb.com
Tue Nov 17 16:54:19 CST 2015


# HG changeset patch
# User Christian Delahousse <cdelahousse at fb.com>
# Date 1447794708 28800
#      Tue Nov 17 13:11:48 2015 -0800
# Node ID 84176ccac91ec4b0c90e0ff6ee3b06e2708ef70a
# Parent  7c9e5aaad4307238a8f6abca9038dd3e4cea9534
dirstate: change debugrebuilddirstate --minimal to use dirstate.rebuild

When debugrebuilddirstate --minimal is called, rebuilding the dirstate was done
outside of the appropriate rebuild function. This patch makes
debugrebuilddirstate use dirstate.rebuild.

This was done to allow our extension to become aware debugrebuilddirstate
--minimal

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -2881,21 +2881,17 @@
     wlock = repo.wlock()
     try:
         dirstate = repo.dirstate
-
+        changedfiles = None
         # See command doc for what minimal does.
         if opts.get('minimal'):
+            manifestfiles = set(ctx.manifest().keys())
             dirstatefiles = set(dirstate)
-            ctxfiles = set(ctx.manifest().keys())
-            for file in (dirstatefiles | ctxfiles):
-                indirstate = file in dirstatefiles
-                inctx = file in ctxfiles
-
-                if indirstate and not inctx and dirstate[file] != 'a':
-                    dirstate.drop(file)
-                elif inctx and not indirstate:
-                    dirstate.normallookup(file)
-        else:
-            dirstate.rebuild(ctx.node(), ctx.manifest())
+            manifestonly = manifestfiles - dirstatefiles
+            dsonly = dirstatefiles - manifestfiles
+            dsnotadded = set(f for f in dsonly if dirstate[f] != 'a')
+            changedfiles =  manifestonly | dsnotadded
+
+        dirstate.rebuild(ctx.node(), ctx.manifest(), changedfiles)
     finally:
         wlock.release()
 
diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py
--- a/mercurial/dirstate.py
+++ b/mercurial/dirstate.py
@@ -639,17 +639,22 @@
 
     def rebuild(self, parent, allfiles, changedfiles=None):
         if changedfiles is None:
+            # Rebuild entire dirstate
             changedfiles = allfiles
-        oldmap = self._map
-        self.clear()
-        for f in allfiles:
-            if f not in changedfiles:
-                self._map[f] = oldmap[f]
+            lastnormaltime = self._lastnormaltime
+            self.clear()
+            self._lastnormaltime = lastnormaltime
+
+        for f in changedfiles:
+            mode = 0o666
+            if f in allfiles and 'x' in allfiles.flags(f):
+                mode = 0o777
+
+            if f in allfiles:
+                self._map[f] = dirstatetuple('n', mode, -1, 0)
             else:
-                if 'x' in allfiles.flags(f):
-                    self._map[f] = dirstatetuple('n', 0o777, -1, 0)
-                else:
-                    self._map[f] = dirstatetuple('n', 0o666, -1, 0)
+                self._map.pop(f, None)
+
         self._pl = (parent, nullid)
         self._dirty = True
 
diff --git a/tests/test-rebuildstate.t b/tests/test-rebuildstate.t
--- a/tests/test-rebuildstate.t
+++ b/tests/test-rebuildstate.t
@@ -88,7 +88,7 @@
   $ hg debugrebuilddirstate --minimal
   $ hg debugdirstate --nodates
   r   0          0 * bar (glob)
-  n   0         -1 * foo (glob)
+  n 644         -1 * foo (glob)
   a   0         -1 * qux (glob)
   $ hg status -A
   A qux


More information about the Mercurial-devel mailing list