changeset 1755:a8f7791e3680

add 'debugrebuildstate' to rebuild the dirstate from a given revision - added and removed files will be lost while recreating the dirstate - modifications are not lost
author Benoit Boissinot <benoit.boissinot@ens-lyon.org>
date Mon, 20 Feb 2006 19:04:56 +0100
parents fdfe89a3962d
children 23012d48ae91 13f8e068d13c
files mercurial/commands.py mercurial/dirstate.py
diffstat 2 files changed, 31 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -985,6 +985,18 @@ def debugancestor(ui, index, rev1, rev2)
     a = r.ancestor(r.lookup(rev1), r.lookup(rev2))
     ui.write("%d:%s\n" % (r.rev(a), hex(a)))
 
+def debugrebuildstate(ui, repo, rev=None):
+    """rebuild the dirstate as it would look like for the given revision"""
+    if not rev:
+        rev = repo.changelog.tip()
+    else:
+        rev = repo.lookup(rev)
+    change = repo.changelog.read(rev)
+    n = change[0]
+    files = repo.manifest.readflags(n)
+    wlock = self.repo.wlock()
+    repo.dirstate.rebuild(rev, files.iteritems())
+
 def debugcheckstate(ui, repo):
     """validate the correctness of the current dirstate"""
     parent1, parent2 = repo.dirstate.parents()
@@ -2359,6 +2371,10 @@ table = {
            _('forcibly copy over an existing managed file'))],
          _('hg copy [OPTION]... [SOURCE]... DEST')),
     "debugancestor": (debugancestor, [], _('debugancestor INDEX REV1 REV2')),
+    "debugrebuildstate":
+        (debugrebuildstate,
+         [('r', 'rev', "", _("revision to rebuild to"))],
+         _('debugrebuildstate [-r REV] [REV]')),
     "debugcheckstate": (debugcheckstate, [], _('debugcheckstate')),
     "debugconfig": (debugconfig, [], _('debugconfig')),
     "debugsetparents": (debugsetparents, [], _('debugsetparents REV1 [REV2]')),
--- a/mercurial/dirstate.py
+++ b/mercurial/dirstate.py
@@ -197,6 +197,19 @@ class dirstate(object):
 
     def clear(self):
         self.map = {}
+        self.copies = {}
+        self.markdirty()
+
+    def rebuild(self, parent, files):
+        self.clear()
+        umask = os.umask(0)
+        os.umask(umask)
+        for f, mode in files:
+            if mode:
+                self.map[f] = ('n', ~umask, -1, 0)
+            else:
+                self.map[f] = ('n', ~umask & 0666, -1, 0)
+        self.pl = (parent, nullid)
         self.markdirty()
 
     def write(self):
@@ -406,7 +419,8 @@ class dirstate(object):
             if type_ == 'n':
                 if not st:
                     st = os.stat(fn)
-                if size != st.st_size or (mode ^ st.st_mode) & 0100:
+                if size >= 0 and (size != st.st_size
+                                  or (mode ^ st.st_mode) & 0100):
                     modified.append(fn)
                 elif time != st.st_mtime:
                     lookup.append(fn)