Merge manifest refactor work
authorMatt Mackall <mpm@selenic.com>
Wed, 09 Aug 2006 15:03:46 -0500
changeset 2836 e78cad1f6b1f
parent 2830 49988d9f0758 (current diff)
parent 2835 a9f5d4149123 (diff)
child 2837 19b3bc840182
Merge manifest refactor work
mercurial/commands.py
mercurial/dirstate.py
mercurial/localrepo.py
mercurial/merge.py
--- a/mercurial/archival.py	Wed Aug 09 13:55:18 2006 -0500
+++ b/mercurial/archival.py	Wed Aug 09 15:03:46 2006 -0500
@@ -169,6 +169,6 @@
     write('.hg_archival.txt', 0644,
           'repo: %s\nnode: %s\n' % (hex(repo.changelog.node(0)), hex(node)))
     for filename, filenode in mf:
-        write(filename, mff[filename] and 0755 or 0644,
+        write(filename, mff.execf(filename) and 0755 or 0644,
               repo.file(filename).read(filenode))
     archiver.done()
--- a/mercurial/commands.py	Wed Aug 09 13:55:18 2006 -0500
+++ b/mercurial/commands.py	Wed Aug 09 15:03:46 2006 -0500
@@ -2151,7 +2151,8 @@
     files.sort()
 
     for f in files:
-        ui.write("%40s %3s %s\n" % (hex(m[f]), mf[f] and "755" or "644", f))
+        ui.write("%40s %3s %s\n" % (hex(m[f]),
+                                    mf.execf(f) and "755" or "644", f))
 
 def merge(ui, repo, node=None, force=None, branch=None):
     """Merge working directory with another revision
--- a/mercurial/dirstate.py	Wed Aug 09 13:55:18 2006 -0500
+++ b/mercurial/dirstate.py	Wed Aug 09 15:03:46 2006 -0500
@@ -238,8 +238,8 @@
         self.clear()
         umask = os.umask(0)
         os.umask(umask)
-        for f, mode in files:
-            if mode:
+        for f in files:
+            if files.execf(f):
                 self.map[f] = ('n', ~umask, -1, 0)
             else:
                 self.map[f] = ('n', ~umask & 0666, -1, 0)
--- a/mercurial/localrepo.py	Wed Aug 09 13:55:18 2006 -0500
+++ b/mercurial/localrepo.py	Wed Aug 09 15:03:46 2006 -0500
@@ -490,9 +490,8 @@
         for f in files:
             try:
                 t = self.wread(f)
-                tm = util.is_exec(self.wjoin(f), mfm.get(f, False))
+                mfm.set(f, util.is_exec(self.wjoin(f), mfm.execf(f)))
                 r = self.file(f)
-                mfm[f] = tm
 
                 (entry, fp1, fp2) = self.checkfilemerge(f, t, r, m1, m2)
                 if entry:
@@ -571,7 +570,7 @@
         for f in commit:
             self.ui.note(f + "\n")
             try:
-                mf1[f] = util.is_exec(self.wjoin(f), mf1.get(f, False))
+                mf1.set(f, util.is_exec(self.wjoin(f), mf1.execf(f)))
                 t = self.wread(f)
             except IOError:
                 self.ui.warn(_("trouble committing %s!\n") % f)
@@ -826,7 +825,7 @@
             else:
                 t = self.file(f).read(m[f])
                 self.wwrite(f, t)
-                util.set_exec(self.wjoin(f), mf[f])
+                util.set_exec(self.wjoin(f), mf.execf(f))
                 self.dirstate.update([f], "n")
 
     def copy(self, source, dest, wlock=None):
--- a/mercurial/manifest.py	Wed Aug 09 13:55:18 2006 -0500
+++ b/mercurial/manifest.py	Wed Aug 09 15:03:46 2006 -0500
@@ -10,6 +10,40 @@
 from demandload import *
 demandload(globals(), "array bisect struct")
 
+class manifestdict(dict):
+    def __init__(self, mapping={}):
+        dict.__init__(self, mapping)
+    def __getitem__(self, f):
+        return self.node(f)
+    def get(self, f, default=None):
+        try:
+            return dict.__getitem__(self, f)[:20]
+        except KeyError:
+            return default
+    def __setitem__(self, f, node):
+        fl = self.flags(f)
+        dict.__setitem__(self, f, node + fl)
+    def node(self, f):
+        return dict.__getitem__(self, f)[:20]
+    def flags(self, f):
+        return dict.get(self, f, "")[20:]
+    def execf(self, f):
+        "test for executable in manifest flags"
+        return "x" in self.flags(f)
+    def linkf(self, f):
+        "test for symlink in manifest flags"
+        return "l" in self.flags(f)
+    def rawset(self, f, node, flags):
+        dict.__setitem__(self, f, node + flags)
+    def set(self, f, execf=False, linkf=False):
+        n = dict.get(self, f, nullid)[:20]
+        fl = ""
+        if execf: fl = "x"
+        if linkf: fl = "l"
+        dict.__setitem__(self, f, n + fl)
+    def copy(self):
+        return manifestdict(dict.copy(self))
+
 class manifest(revlog):
     def __init__(self, opener, defversion=REVLOGV0):
         self.mapcache = None
@@ -18,26 +52,21 @@
                         defversion)
 
     def read(self, node):
-        if node == nullid: return {} # don't upset local cache
+        if node == nullid: return manifestdict() # don't upset local cache
         if self.mapcache and self.mapcache[0] == node:
             return self.mapcache[1]
         text = self.revision(node)
-        map = {}
-        flag = {}
         self.listcache = array.array('c', text)
         lines = text.splitlines(1)
+        mapping = manifestdict()
         for l in lines:
             (f, n) = l.split('\0')
-            map[f] = bin(n[:40])
-            flag[f] = (n[40:-1] == "x")
-        self.mapcache = (node, map, flag)
-        return map
+            mapping.rawset(f, bin(n[:40]), n[40:-1])
+        self.mapcache = (node, mapping)
+        return mapping
 
     def readflags(self, node):
-        if node == nullid: return {} # don't upset local cache
-        if not self.mapcache or self.mapcache[0] != node:
-            self.read(node)
-        return self.mapcache[2]
+        return self.read(node)
 
     def diff(self, a, b):
         return mdiff.textdiff(str(a), str(b))
@@ -86,7 +115,7 @@
         '''look up entry for a single file efficiently.
         return (node, flag) pair if found, (None, None) if not.'''
         if self.mapcache and node == self.mapcache[0]:
-            return self.mapcache[1].get(f), self.mapcache[2].get(f)
+            return self.mapcache[1].get(f), self.mapcache[1].flags(f)
         text = self.revision(node)
         start, end = self._search(text, f)
         if start == end:
@@ -123,9 +152,7 @@
 
             # if this is changed to support newlines in filenames,
             # be sure to check the templates/ dir again (especially *-raw.tmpl)
-            text = ["%s\000%s%s\n" %
-                            (f, hex(map[f]), flags[f] and "x" or '')
-                            for f in files]
+            text = ["%s\000%s%s\n" % (f, hex(map[f]), flags.flags(f)) for f in files]
             self.listcache = array.array('c', "".join(text))
             cachedelta = None
         else:
@@ -151,8 +178,7 @@
                 # bs will either be the index of the item or the insert point
                 start, end = self._search(addbuf, f, start)
                 if w[1] == 0:
-                    l = "%s\000%s%s\n" % (f, hex(map[f]),
-                                          flags[f] and "x" or '')
+                    l = "%s\000%s%s\n" % (f, hex(map[f]), flags.flags(f))
                 else:
                     l = ""
                 if start == end and w[1] == 1:
@@ -183,6 +209,6 @@
 
         n = self.addrevision(buffer(self.listcache), transaction, link, p1,  \
                              p2, cachedelta)
-        self.mapcache = (n, map, flags)
+        self.mapcache = (n, map)
 
         return n
--- a/mercurial/merge.py	Wed Aug 09 13:55:18 2006 -0500
+++ b/mercurial/merge.py	Wed Aug 09 15:03:46 2006 -0500
@@ -118,7 +118,7 @@
 
     for f in added + modified + unknown:
         mw[f] = ""
-        mfw[f] = util.is_exec(repo.wjoin(f), mfw.get(f, False))
+        mfw.set(f, util.is_exec(repo.wjoin(f), mfw.execf(f)))
 
     for f in deleted + removed:
         if f in mw:
@@ -155,7 +155,7 @@
                     repo.ui.debug(_(" %s versions differ, resolve\n") % f)
                     # merge executable bits
                     # "if we changed or they changed, change in merge"
-                    a, b, c = mfa.get(f, 0), mfw[f], mf2[f]
+                    a, b, c = mfa.execf(f), mfw.execf(f), mf2.execf(f)
                     mode = ((a^b) | (a^c)) ^ a
                     merge[f] = (m1.get(f, nullid), m2[f], mode)
                     s = 1
@@ -171,12 +171,12 @@
                 # we need to reset the dirstate if the file was added
                 get[f] = m2[f]
 
-            if not s and mfw[f] != mf2[f]:
+            if not s and mfw.execf(f) != mf2.execf(f):
                 if overwrite:
                     repo.ui.debug(_(" updating permissions for %s\n") % f)
-                    util.set_exec(repo.wjoin(f), mf2[f])
+                    util.set_exec(repo.wjoin(f), mf2.execf(f))
                 else:
-                    a, b, c = mfa.get(f, 0), mfw[f], mf2[f]
+                    a, b, c = mfa.execf(f), mfw.execf(f), mf2.execf(f)
                     mode = ((a^b) | (a^c)) ^ a
                     if mode != b:
                         repo.ui.debug(_(" updating permissions for %s\n")
@@ -259,7 +259,7 @@
         repo.ui.note(_("getting %s\n") % f)
         t = repo.file(f).read(get[f])
         repo.wwrite(f, t)
-        util.set_exec(repo.wjoin(f), mf2[f])
+        util.set_exec(repo.wjoin(f), mf2.execf(f))
         if not partial:
             if branchmerge:
                 repo.dirstate.update([f], 'n', st_mtime=-1)