changeset 10921:fb89cd21a7a0 stable

workingctx: correctly compute the flag for noexec filesystems+merge This bug happens if the filesystem doesn't support exec-bit, during merges, for example in 24ed7a541f23 on the hg repo. If f is not in p1, but is in p2 and has the x-bit in p2, since the dirstate is based on p1, and the FS doesn't support the exec-bit, the dirstate can't "guess" the right bit. We instead fix it in workingcontext.flags()/manifest.
author Benoit Boissinot <benoit.boissinot@ens-lyon.org>
date Thu, 15 Apr 2010 18:08:48 +0200
parents bce47e253b61
children fa1f5de99fb2 1782278bab8a
files mercurial/context.py
diffstat 1 files changed, 26 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/context.py	Thu Apr 15 15:21:41 2010 +0200
+++ b/mercurial/context.py	Thu Apr 15 18:08:48 2010 +0200
@@ -589,12 +589,23 @@
 
         man = self._parents[0].manifest().copy()
         copied = self._repo.dirstate.copies()
-        cf = lambda x: man.flags(copied.get(x, x))
+        if len(self._parents) > 1:
+            man2 = self.p2().manifest()
+            def getman(f):
+                if f in man:
+                    return man
+                return man2
+        else:
+            getman = lambda f: man
+        def cf(f):
+            f = copied.get(f, f)
+            return getman(f).flags(f)
         ff = self._repo.dirstate.flagfunc(cf)
         modified, added, removed, deleted, unknown = self._status[:5]
         for i, l in (("a", added), ("m", modified), ("u", unknown)):
             for f in l:
-                man[f] = man.get(copied.get(f, f), nullid) + i
+                orig = copied.get(f, f)
+                man[f] = getman(orig).get(orig, nullid) + i
                 try:
                     man.set(f, ff(f))
                 except OSError:
@@ -669,16 +680,21 @@
             except KeyError:
                 return ''
 
-        pnode = self._parents[0].changeset()[0]
         orig = self._repo.dirstate.copies().get(path, path)
-        node, flag = self._repo.manifest.find(pnode, orig)
-        try:
-            ff = self._repo.dirstate.flagfunc(lambda x: flag or '')
-            return ff(path)
-        except OSError:
-            pass
 
-        if not node or path in self.deleted() or path in self.removed():
+        def findflag(ctx):
+            mnode = ctx.changeset()[0]
+            node, flag = self._repo.manifest.find(mnode, orig)
+            ff = self._repo.dirstate.flagfunc(lambda x: flag or None)
+            try:
+                return ff(orig)
+            except OSError:
+                pass
+
+        flag = findflag(self._parents[0])
+        if flag is None and len(self.parents()) > 1:
+            flag = findflag(self._parents[1])
+        if flag is None or self._repo.dirstate[path] == 'r':
             return ''
         return flag