Mercurial > hg
comparison mercurial/context.py @ 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 | 08a0f04b56bd |
children | c1d375e93ee8 |
comparison
equal
deleted
inserted
replaced
10917:bce47e253b61 | 10921:fb89cd21a7a0 |
---|---|
587 def _manifest(self): | 587 def _manifest(self): |
588 """generate a manifest corresponding to the working directory""" | 588 """generate a manifest corresponding to the working directory""" |
589 | 589 |
590 man = self._parents[0].manifest().copy() | 590 man = self._parents[0].manifest().copy() |
591 copied = self._repo.dirstate.copies() | 591 copied = self._repo.dirstate.copies() |
592 cf = lambda x: man.flags(copied.get(x, x)) | 592 if len(self._parents) > 1: |
593 man2 = self.p2().manifest() | |
594 def getman(f): | |
595 if f in man: | |
596 return man | |
597 return man2 | |
598 else: | |
599 getman = lambda f: man | |
600 def cf(f): | |
601 f = copied.get(f, f) | |
602 return getman(f).flags(f) | |
593 ff = self._repo.dirstate.flagfunc(cf) | 603 ff = self._repo.dirstate.flagfunc(cf) |
594 modified, added, removed, deleted, unknown = self._status[:5] | 604 modified, added, removed, deleted, unknown = self._status[:5] |
595 for i, l in (("a", added), ("m", modified), ("u", unknown)): | 605 for i, l in (("a", added), ("m", modified), ("u", unknown)): |
596 for f in l: | 606 for f in l: |
597 man[f] = man.get(copied.get(f, f), nullid) + i | 607 orig = copied.get(f, f) |
608 man[f] = getman(orig).get(orig, nullid) + i | |
598 try: | 609 try: |
599 man.set(f, ff(f)) | 610 man.set(f, ff(f)) |
600 except OSError: | 611 except OSError: |
601 pass | 612 pass |
602 | 613 |
667 try: | 678 try: |
668 return self._manifest.flags(path) | 679 return self._manifest.flags(path) |
669 except KeyError: | 680 except KeyError: |
670 return '' | 681 return '' |
671 | 682 |
672 pnode = self._parents[0].changeset()[0] | |
673 orig = self._repo.dirstate.copies().get(path, path) | 683 orig = self._repo.dirstate.copies().get(path, path) |
674 node, flag = self._repo.manifest.find(pnode, orig) | 684 |
675 try: | 685 def findflag(ctx): |
676 ff = self._repo.dirstate.flagfunc(lambda x: flag or '') | 686 mnode = ctx.changeset()[0] |
677 return ff(path) | 687 node, flag = self._repo.manifest.find(mnode, orig) |
678 except OSError: | 688 ff = self._repo.dirstate.flagfunc(lambda x: flag or None) |
679 pass | 689 try: |
680 | 690 return ff(orig) |
681 if not node or path in self.deleted() or path in self.removed(): | 691 except OSError: |
692 pass | |
693 | |
694 flag = findflag(self._parents[0]) | |
695 if flag is None and len(self.parents()) > 1: | |
696 flag = findflag(self._parents[1]) | |
697 if flag is None or self._repo.dirstate[path] == 'r': | |
682 return '' | 698 return '' |
683 return flag | 699 return flag |
684 | 700 |
685 def filectx(self, path, filelog=None): | 701 def filectx(self, path, filelog=None): |
686 """get a file context from the working directory""" | 702 """get a file context from the working directory""" |