Mercurial > public > mercurial-scm > hg
comparison mercurial/context.py @ 32651:c850f0ed54c1 stable 4.2.1
status: don't crash if a lookup file disappears
This can happen if another process (even another hg process!) comes along and
removes the file at that time.
This partly resolves issue5584, but not completely -- a bogus dirstate update
can still happen. However, the full fix is too involved for stable.
author | Siddharth Agarwal <sid0@fb.com> |
---|---|
date | Fri, 02 Jun 2017 22:27:52 -0700 |
parents | a457da5296a5 |
children | 9929af2b09b4 |
comparison
equal
deleted
inserted
replaced
32608:85b978031a75 | 32651:c850f0ed54c1 |
---|---|
1611 return sane | 1611 return sane |
1612 | 1612 |
1613 def _checklookup(self, files): | 1613 def _checklookup(self, files): |
1614 # check for any possibly clean files | 1614 # check for any possibly clean files |
1615 if not files: | 1615 if not files: |
1616 return [], [] | 1616 return [], [], [] |
1617 | 1617 |
1618 modified = [] | 1618 modified = [] |
1619 deleted = [] | |
1619 fixup = [] | 1620 fixup = [] |
1620 pctx = self._parents[0] | 1621 pctx = self._parents[0] |
1621 # do a full compare of any files that might have changed | 1622 # do a full compare of any files that might have changed |
1622 for f in sorted(files): | 1623 for f in sorted(files): |
1623 if (f not in pctx or self.flags(f) != pctx.flags(f) | 1624 try: |
1624 or pctx[f].cmp(self[f])): | 1625 # This will return True for a file that got replaced by a |
1625 modified.append(f) | 1626 # directory in the interim, but fixing that is pretty hard. |
1626 else: | 1627 if (f not in pctx or self.flags(f) != pctx.flags(f) |
1627 fixup.append(f) | 1628 or pctx[f].cmp(self[f])): |
1629 modified.append(f) | |
1630 else: | |
1631 fixup.append(f) | |
1632 except (IOError, OSError): | |
1633 # A file become inaccessible in between? Mark it as deleted, | |
1634 # matching dirstate behavior (issue5584). | |
1635 # The dirstate has more complex behavior around whether a | |
1636 # missing file matches a directory, etc, but we don't need to | |
1637 # bother with that: if f has made it to this point, we're sure | |
1638 # it's in the dirstate. | |
1639 deleted.append(f) | |
1628 | 1640 |
1629 # update dirstate for files that are actually clean | 1641 # update dirstate for files that are actually clean |
1630 if fixup: | 1642 if fixup: |
1631 try: | 1643 try: |
1632 # updating the dirstate is optional | 1644 # updating the dirstate is optional |
1642 # after this block from doing so for subsequent | 1654 # after this block from doing so for subsequent |
1643 # changing files | 1655 # changing files |
1644 self._repo.dirstate.write(self._repo.currenttransaction()) | 1656 self._repo.dirstate.write(self._repo.currenttransaction()) |
1645 except error.LockError: | 1657 except error.LockError: |
1646 pass | 1658 pass |
1647 return modified, fixup | 1659 return modified, deleted, fixup |
1648 | 1660 |
1649 def _dirstatestatus(self, match=None, ignored=False, clean=False, | 1661 def _dirstatestatus(self, match=None, ignored=False, clean=False, |
1650 unknown=False): | 1662 unknown=False): |
1651 '''Gets the status from the dirstate -- internal use only.''' | 1663 '''Gets the status from the dirstate -- internal use only.''' |
1652 listignored, listclean, listunknown = ignored, clean, unknown | 1664 listignored, listclean, listunknown = ignored, clean, unknown |
1657 cmp, s = self._repo.dirstate.status(match, subrepos, listignored, | 1669 cmp, s = self._repo.dirstate.status(match, subrepos, listignored, |
1658 listclean, listunknown) | 1670 listclean, listunknown) |
1659 | 1671 |
1660 # check for any possibly clean files | 1672 # check for any possibly clean files |
1661 if cmp: | 1673 if cmp: |
1662 modified2, fixup = self._checklookup(cmp) | 1674 modified2, deleted2, fixup = self._checklookup(cmp) |
1663 s.modified.extend(modified2) | 1675 s.modified.extend(modified2) |
1676 s.deleted.extend(deleted2) | |
1664 | 1677 |
1665 # update dirstate for files that are actually clean | 1678 # update dirstate for files that are actually clean |
1666 if fixup and listclean: | 1679 if fixup and listclean: |
1667 s.clean.extend(fixup) | 1680 s.clean.extend(fixup) |
1668 | 1681 |