Mercurial > public > mercurial-scm > hg-stable
diff mercurial/context.py @ 32141: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 |
line wrap: on
line diff
--- a/mercurial/context.py Fri Jun 02 10:44:40 2017 +0200 +++ b/mercurial/context.py Fri Jun 02 22:27:52 2017 -0700 @@ -1613,18 +1613,30 @@ def _checklookup(self, files): # check for any possibly clean files if not files: - return [], [] + return [], [], [] modified = [] + deleted = [] fixup = [] pctx = self._parents[0] # do a full compare of any files that might have changed for f in sorted(files): - if (f not in pctx or self.flags(f) != pctx.flags(f) - or pctx[f].cmp(self[f])): - modified.append(f) - else: - fixup.append(f) + try: + # This will return True for a file that got replaced by a + # directory in the interim, but fixing that is pretty hard. + if (f not in pctx or self.flags(f) != pctx.flags(f) + or pctx[f].cmp(self[f])): + modified.append(f) + else: + fixup.append(f) + except (IOError, OSError): + # A file become inaccessible in between? Mark it as deleted, + # matching dirstate behavior (issue5584). + # The dirstate has more complex behavior around whether a + # missing file matches a directory, etc, but we don't need to + # bother with that: if f has made it to this point, we're sure + # it's in the dirstate. + deleted.append(f) # update dirstate for files that are actually clean if fixup: @@ -1644,7 +1656,7 @@ self._repo.dirstate.write(self._repo.currenttransaction()) except error.LockError: pass - return modified, fixup + return modified, deleted, fixup def _dirstatestatus(self, match=None, ignored=False, clean=False, unknown=False): @@ -1659,8 +1671,9 @@ # check for any possibly clean files if cmp: - modified2, fixup = self._checklookup(cmp) + modified2, deleted2, fixup = self._checklookup(cmp) s.modified.extend(modified2) + s.deleted.extend(deleted2) # update dirstate for files that are actually clean if fixup and listclean: