merge with mpm.
authorVadim Gelfer <vadim.gelfer@gmail.com>
Sat, 12 Aug 2006 11:53:12 -0700
changeset 2855 cdbca3d59518
parent 2853 619f1c65384c (current diff)
parent 2841 e3fb4223e750 (diff)
child 2856 a3c73c9679d2
merge with mpm.
hgext/mq.py
mercurial/commands.py
--- a/hgext/mq.py	Fri Aug 11 09:11:54 2006 +0200
+++ b/hgext/mq.py	Sat Aug 12 11:53:12 2006 -0700
@@ -888,7 +888,6 @@
             top = self.check_toppatch(repo)
             qp = self.qparents(repo, rev)
             changes = repo.changelog.read(qp)
-            mf1 = repo.manifest.readflags(changes[0])
             mmap = repo.manifest.read(changes[0])
             (c, a, r, d, u) = repo.changes(qp, top)
             if d:
@@ -897,7 +896,7 @@
                 getfile(f, mmap[f])
             for f in r:
                 getfile(f, mmap[f])
-                util.set_exec(repo.wjoin(f), mf1[f])
+                util.set_exec(repo.wjoin(f), mmap.execf[f])
             repo.dirstate.update(c + r, 'n')
             for f in a:
                 try: os.unlink(repo.wjoin(f))
--- a/mercurial/archival.py	Fri Aug 11 09:11:54 2006 +0200
+++ b/mercurial/archival.py	Sat Aug 12 11:53:12 2006 -0700
@@ -164,11 +164,10 @@
     mn = change[0]
     archiver = archivers[kind](dest, prefix, mtime or change[2][0])
     mf = repo.manifest.read(mn).items()
-    mff = repo.manifest.readflags(mn)
     mf.sort()
     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, mf.execf(filename) and 0755 or 0644,
               repo.file(filename).read(filenode))
     archiver.done()
--- a/mercurial/commands.py	Fri Aug 11 09:11:54 2006 +0200
+++ b/mercurial/commands.py	Sat Aug 12 11:53:12 2006 -0700
@@ -1333,9 +1333,9 @@
         rev = repo.lookup(rev)
     change = repo.changelog.read(rev)
     n = change[0]
-    files = repo.manifest.readflags(n)
+    files = repo.manifest.read(n)
     wlock = repo.wlock()
-    repo.dirstate.rebuild(rev, files.iteritems())
+    repo.dirstate.rebuild(rev, files)
 
 def debugcheckstate(ui, repo):
     """validate the correctness of the current dirstate"""
@@ -2146,12 +2146,12 @@
     else:
         n = repo.manifest.tip()
     m = repo.manifest.read(n)
-    mf = repo.manifest.readflags(n)
     files = m.keys()
     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]),
+                                    m.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	Fri Aug 11 09:11:54 2006 +0200
+++ b/mercurial/dirstate.py	Sat Aug 12 11:53:12 2006 -0700
@@ -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/hgweb/hgweb_mod.py	Fri Aug 11 09:11:54 2006 +0200
+++ b/mercurial/hgweb/hgweb_mod.py	Sat Aug 12 11:53:12 2006 -0700
@@ -398,7 +398,7 @@
                      parent=self.siblings(fl.parents(n), fl.rev, file=f),
                      child=self.siblings(fl.children(n), fl.rev, file=f),
                      rename=self.renamelink(fl, n),
-                     permissions=self.repo.manifest.readflags(mfn)[f])
+                     permissions=self.repo.manifest.read(mfn).execf[f])
 
     def fileannotate(self, f, node):
         bcache = {}
@@ -452,7 +452,7 @@
                      rename=self.renamelink(fl, n),
                      parent=self.siblings(fl.parents(n), fl.rev, file=f),
                      child=self.siblings(fl.children(n), fl.rev, file=f),
-                     permissions=self.repo.manifest.readflags(mfn)[f])
+                     permissions=self.repo.manifest.read(mfn).execf[f])
 
     def manifest(self, mnode, path):
         man = self.repo.manifest
@@ -462,7 +462,6 @@
         rev = man.rev(mn)
         changerev = man.linkrev(mn)
         node = self.repo.changelog.node(changerev)
-        mff = man.readflags(mn)
 
         files = {}
 
@@ -496,7 +495,7 @@
                        "filenode": hex(fnode),
                        "parity": self.stripes(parity),
                        "basename": f,
-                       "permissions": mff[full]}
+                       "permissions": mf.execf[full]}
                 parity += 1
 
         def dirlist(**map):
--- a/mercurial/localrepo.py	Fri Aug 11 09:11:54 2006 +0200
+++ b/mercurial/localrepo.py	Sat Aug 12 11:53:12 2006 -0700
@@ -470,8 +470,7 @@
         p2 = p2 or self.dirstate.parents()[1] or nullid
         c1 = self.changelog.read(p1)
         c2 = self.changelog.read(p2)
-        m1 = self.manifest.read(c1[0])
-        mf1 = self.manifest.readflags(c1[0])
+        m1 = self.manifest.read(c1[0]).copy()
         m2 = self.manifest.read(c2[0])
         changed = []
 
@@ -484,36 +483,33 @@
             wlock = self.wlock()
         l = self.lock()
         tr = self.transaction()
-        mm = m1.copy()
-        mfm = mf1.copy()
         linkrev = self.changelog.count()
         for f in files:
             try:
                 t = self.wread(f)
-                tm = util.is_exec(self.wjoin(f), mfm.get(f, False))
+                m1.set(f, util.is_exec(self.wjoin(f), m1.execf(f)))
                 r = self.file(f)
-                mfm[f] = tm
 
                 (entry, fp1, fp2) = self.checkfilemerge(f, t, r, m1, m2)
                 if entry:
-                    mm[f] = entry
+                    m1[f] = entry
                     continue
 
-                mm[f] = r.add(t, {}, tr, linkrev, fp1, fp2)
+                m1[f] = r.add(t, {}, tr, linkrev, fp1, fp2)
                 changed.append(f)
                 if update_dirstate:
                     self.dirstate.update([f], "n")
             except IOError:
                 try:
-                    del mm[f]
-                    del mfm[f]
+                    del m1[f]
+                    del m1[f]
                     if update_dirstate:
                         self.dirstate.forget([f])
                 except:
                     # deleted from p2?
                     pass
 
-        mnode = self.manifest.add(mm, mfm, tr, linkrev, c1[0], c2[0])
+        mnode = self.manifest.add(m1, tr, linkrev, c1[0], c2[0])
         user = user or self.ui.username()
         n = self.changelog.add(mnode, changed, text, tr, p1, p2, user, date)
         tr.close()
@@ -544,8 +540,7 @@
         p1, p2 = self.dirstate.parents()
         c1 = self.changelog.read(p1)
         c2 = self.changelog.read(p2)
-        m1 = self.manifest.read(c1[0])
-        mf1 = self.manifest.readflags(c1[0])
+        m1 = self.manifest.read(c1[0]).copy()
         m2 = self.manifest.read(c2[0])
 
         if not commit and not remove and not force and p2 == nullid:
@@ -571,7 +566,7 @@
         for f in commit:
             self.ui.note(f + "\n")
             try:
-                mf1[f] = util.is_exec(self.wjoin(f), mf1.get(f, False))
+                m1.set(f, util.is_exec(self.wjoin(f), m1.execf(f)))
                 t = self.wread(f)
             except IOError:
                 self.ui.warn(_("trouble committing %s!\n") % f)
@@ -598,12 +593,11 @@
             changed.append(f)
 
         # update manifest
-        m1 = m1.copy()
         m1.update(new)
         for f in remove:
             if f in m1:
                 del m1[f]
-        mn = self.manifest.add(m1, mf1, tr, linkrev, c1[0], c2[0],
+        mn = self.manifest.add(m1, tr, linkrev, c1[0], c2[0],
                                (new, remove))
 
         # add changeset
@@ -816,7 +810,6 @@
     def undelete(self, list, wlock=None):
         p = self.dirstate.parents()[0]
         mn = self.changelog.read(p)[0]
-        mf = self.manifest.readflags(mn)
         m = self.manifest.read(mn)
         if not wlock:
             wlock = self.wlock()
@@ -826,7 +819,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), m.execf(f))
                 self.dirstate.update([f], "n")
 
     def copy(self, source, dest, wlock=None):
--- a/mercurial/manifest.py	Fri Aug 11 09:11:54 2006 +0200
+++ b/mercurial/manifest.py	Sat Aug 12 11:53:12 2006 -0700
@@ -10,6 +10,28 @@
 from demandload import *
 demandload(globals(), "array bisect struct")
 
+class manifestdict(dict):
+    def __init__(self, mapping={}, flags={}):
+        dict.__init__(self, mapping)
+        self._flags = flags
+    def flags(self, f):
+        return self._flags.get(f, "")
+    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, entry):
+        self[f] = bin(entry[:40])
+        fl = entry[40:-1]
+        if fl: self._flags[f] = fl
+    def set(self, f, execf=False, linkf=False):
+        if execf: self._flags[f] = "x"
+        if linkf: self._flags[f] = "x"
+    def copy(self):
+        return manifestdict(dict.copy(self), dict.copy(self._flags))
+
 class manifest(revlog):
     def __init__(self, opener, defversion=REVLOGV0):
         self.mapcache = None
@@ -18,26 +40,18 @@
                         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
-
-    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]
+            mapping.rawset(f, n)
+        self.mapcache = (node, mapping)
+        return mapping
 
     def diff(self, a, b):
         return mdiff.textdiff(str(a), str(b))
@@ -86,7 +100,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:
@@ -95,7 +109,7 @@
         f, n = l.split('\0')
         return bin(n[:40]), n[40:-1] == 'x'
 
-    def add(self, map, flags, transaction, link, p1=None, p2=None,
+    def add(self, map, transaction, link, p1=None, p2=None,
             changed=None):
         # apply the changes collected during the bisect loop to our addlist
         # return a delta suitable for addrevision
@@ -123,9 +137,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]), map.flags(f)) for f in files]
             self.listcache = array.array('c', "".join(text))
             cachedelta = None
         else:
@@ -151,8 +163,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]), map.flags(f))
                 else:
                     l = ""
                 if start == end and w[1] == 1:
@@ -183,6 +194,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	Fri Aug 11 09:11:54 2006 +0200
+++ b/mercurial/merge.py	Sat Aug 12 11:53:12 2006 -0700
@@ -84,11 +84,8 @@
     m2n = repo.changelog.read(p2)[0]
     man = repo.manifest.ancestor(m1n, m2n)
     m1 = repo.manifest.read(m1n)
-    mf1 = repo.manifest.readflags(m1n)
     m2 = repo.manifest.read(m2n).copy()
-    mf2 = repo.manifest.readflags(m2n)
     ma = repo.manifest.read(man)
-    mfa = repo.manifest.readflags(man)
 
     if not forcemerge and not overwrite:
         for f in unknown:
@@ -113,12 +110,11 @@
 
     # construct a working dir manifest
     mw = m1.copy()
-    mfw = mf1.copy()
     umap = dict.fromkeys(unknown)
 
     for f in added + modified + unknown:
         mw[f] = ""
-        mfw[f] = util.is_exec(repo.wjoin(f), mfw.get(f, False))
+        mw.set(f, util.is_exec(repo.wjoin(f), mw.execf(f)))
 
     for f in deleted + removed:
         if f in mw:
@@ -155,28 +151,28 @@
                     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 = ma.execf(f), mw.execf(f), m2.execf(f)
                     mode = ((a^b) | (a^c)) ^ a
-                    merge[f] = (m1.get(f, nullid), m2[f], mode)
+                    merge[f] = (mode, m1.get(f, nullid), m2[f])
                     s = 1
                 # are we clobbering?
                 # is remote's version newer?
                 # or are we going back in time?
                 elif overwrite or m2[f] != a or (p2 == pa and mw[f] == m1[f]):
                     repo.ui.debug(_(" remote %s is newer, get\n") % f)
-                    get[f] = m2[f]
+                    get[f] = (m2.execf(f), m2[f])
                     s = 1
             elif f in umap or f in added:
                 # this unknown file is the same as the checkout
                 # we need to reset the dirstate if the file was added
-                get[f] = m2[f]
+                get[f] = (m2.execf(f), m2[f])
 
-            if not s and mfw[f] != mf2[f]:
+            if not s and mw.execf(f) != m2.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), m2.execf(f))
                 else:
-                    a, b, c = mfa.get(f, 0), mfw[f], mf2[f]
+                    a, b, c = ma.execf(f), mw.execf(f), m2.execf(f)
                     mode = ((a^b) | (a^c)) ^ a
                     if mode != b:
                         repo.ui.debug(_(" updating permissions for %s\n")
@@ -221,14 +217,14 @@
                     (_("remote changed %s which local deleted\n") % f) +
                      _("(k)eep or (d)elete?"), _("[kd]"), _("k"))
             if r == _("k"):
-                get[f] = n
+                get[f] = (m2.execf(f), n)
         elif f not in ma:
             repo.ui.debug(_("remote created %s\n") % f)
-            get[f] = n
+            get[f] = (m2.execf(f), n)
         else:
             if overwrite or p2 == pa: # going backwards?
                 repo.ui.debug(_("local deleted %s, recreating\n") % f)
-                get[f] = n
+                get[f] = (m2.execf(f), n)
             else:
                 repo.ui.debug(_("local deleted %s\n") % f)
 
@@ -236,7 +232,7 @@
 
     if overwrite:
         for f in merge:
-            get[f] = merge[f][1]
+            get[f] = merge[f][:2]
         merge = {}
 
     if linear_path or overwrite:
@@ -254,12 +250,13 @@
     files = get.keys()
     files.sort()
     for f in files:
+        flag, node = get[f]
         if f[0] == "/":
             continue
         repo.ui.note(_("getting %s\n") % f)
-        t = repo.file(f).read(get[f])
+        t = repo.file(f).read(node)
         repo.wwrite(f, t)
-        util.set_exec(repo.wjoin(f), mf2[f])
+        util.set_exec(repo.wjoin(f), flag)
         if not partial:
             if branchmerge:
                 repo.dirstate.update([f], 'n', st_mtime=-1)
@@ -272,7 +269,7 @@
     files.sort()
     for f in files:
         repo.ui.status(_("merging %s\n") % f)
-        my, other, flag = merge[f]
+        flag, my, other = merge[f]
         ret = merge3(repo, f, my, other, xp1, xp2)
         if ret:
             unresolved.append(f)