mercurial/context.py
changeset 48390 322525db4c98
parent 48381 41f40f35278a
child 48395 9ae0353c9f5d
equal deleted inserted replaced
48389:03644a929d6e 48390:322525db4c98
  1794                     )
  1794                     )
  1795                     continue
  1795                     continue
  1796             sane.append(f)
  1796             sane.append(f)
  1797         return sane
  1797         return sane
  1798 
  1798 
  1799     def _checklookup(self, files):
  1799     def _checklookup(self, files, mtime_boundary):
  1800         # check for any possibly clean files
  1800         # check for any possibly clean files
  1801         if not files:
  1801         if not files:
  1802             return [], [], []
  1802             return [], [], [], []
  1803 
  1803 
  1804         modified = []
  1804         modified = []
  1805         deleted = []
  1805         deleted = []
       
  1806         clean = []
  1806         fixup = []
  1807         fixup = []
  1807         pctx = self._parents[0]
  1808         pctx = self._parents[0]
  1808         # do a full compare of any files that might have changed
  1809         # do a full compare of any files that might have changed
  1809         for f in sorted(files):
  1810         for f in sorted(files):
  1810             try:
  1811             try:
  1814                     f not in pctx
  1815                     f not in pctx
  1815                     or self.flags(f) != pctx.flags(f)
  1816                     or self.flags(f) != pctx.flags(f)
  1816                     or pctx[f].cmp(self[f])
  1817                     or pctx[f].cmp(self[f])
  1817                 ):
  1818                 ):
  1818                     modified.append(f)
  1819                     modified.append(f)
       
  1820                 elif mtime_boundary is None:
       
  1821                     clean.append(f)
  1819                 else:
  1822                 else:
  1820                     # XXX note that we have a race windows here since we gather
       
  1821                     # the stats after we compared so the file might have
       
  1822                     # changed.
       
  1823                     #
       
  1824                     # However this have always been the case and the
       
  1825                     # refactoring moving the code here is improving the
       
  1826                     # situation by narrowing the race and moving the two steps
       
  1827                     # (comparison + stat) in the same location.
       
  1828                     #
       
  1829                     # Making this code "correct" is now possible.
       
  1830                     s = self[f].lstat()
  1823                     s = self[f].lstat()
  1831                     mode = s.st_mode
  1824                     mode = s.st_mode
  1832                     size = s.st_size
  1825                     size = s.st_size
  1833                     mtime = timestamp.mtime_of(s)
  1826                     file_mtime = timestamp.mtime_of(s)
  1834                     fixup.append((f, (mode, size, mtime)))
  1827                     cache_info = (mode, size, file_mtime)
       
  1828 
       
  1829                     file_second = file_mtime[0]
       
  1830                     boundary_second = mtime_boundary[0]
       
  1831                     # If the mtime of the ambiguous file is younger (or equal)
       
  1832                     # to the starting point of the `status` walk, we cannot
       
  1833                     # garantee that another, racy, write will not happen right
       
  1834                     # after with the same mtime and we cannot cache the
       
  1835                     # information.
       
  1836                     #
       
  1837                     # However is the mtime is far away in the future, this is
       
  1838                     # likely some mismatch between the current clock and
       
  1839                     # previous file system operation. So mtime more than one days
       
  1840                     # in the future are considered fine.
       
  1841                     if (
       
  1842                         boundary_second
       
  1843                         <= file_second
       
  1844                         < (3600 * 24 + boundary_second)
       
  1845                     ):
       
  1846                         clean.append(f)
       
  1847                     else:
       
  1848                         fixup.append((f, cache_info))
  1835             except (IOError, OSError):
  1849             except (IOError, OSError):
  1836                 # A file become inaccessible in between? Mark it as deleted,
  1850                 # A file become inaccessible in between? Mark it as deleted,
  1837                 # matching dirstate behavior (issue5584).
  1851                 # matching dirstate behavior (issue5584).
  1838                 # The dirstate has more complex behavior around whether a
  1852                 # The dirstate has more complex behavior around whether a
  1839                 # missing file matches a directory, etc, but we don't need to
  1853                 # missing file matches a directory, etc, but we don't need to
  1840                 # bother with that: if f has made it to this point, we're sure
  1854                 # bother with that: if f has made it to this point, we're sure
  1841                 # it's in the dirstate.
  1855                 # it's in the dirstate.
  1842                 deleted.append(f)
  1856                 deleted.append(f)
  1843 
  1857 
  1844         return modified, deleted, fixup
  1858         return modified, deleted, clean, fixup
  1845 
  1859 
  1846     def _poststatusfixup(self, status, fixup):
  1860     def _poststatusfixup(self, status, fixup):
  1847         """update dirstate for files that are actually clean"""
  1861         """update dirstate for files that are actually clean"""
  1848         poststatus = self._repo.postdsstatus()
  1862         poststatus = self._repo.postdsstatus()
  1849         if fixup or poststatus or self._repo.dirstate._dirty:
  1863         if fixup or poststatus or self._repo.dirstate._dirty:
  1893     def _dirstatestatus(self, match, ignored=False, clean=False, unknown=False):
  1907     def _dirstatestatus(self, match, ignored=False, clean=False, unknown=False):
  1894         '''Gets the status from the dirstate -- internal use only.'''
  1908         '''Gets the status from the dirstate -- internal use only.'''
  1895         subrepos = []
  1909         subrepos = []
  1896         if b'.hgsub' in self:
  1910         if b'.hgsub' in self:
  1897             subrepos = sorted(self.substate)
  1911             subrepos = sorted(self.substate)
  1898         cmp, s = self._repo.dirstate.status(
  1912         cmp, s, mtime_boundary = self._repo.dirstate.status(
  1899             match, subrepos, ignored=ignored, clean=clean, unknown=unknown
  1913             match, subrepos, ignored=ignored, clean=clean, unknown=unknown
  1900         )
  1914         )
  1901 
  1915 
  1902         # check for any possibly clean files
  1916         # check for any possibly clean files
  1903         fixup = []
  1917         fixup = []
  1904         if cmp:
  1918         if cmp:
  1905             modified2, deleted2, fixup = self._checklookup(cmp)
  1919             modified2, deleted2, clean_set, fixup = self._checklookup(
       
  1920                 cmp, mtime_boundary
       
  1921             )
  1906             s.modified.extend(modified2)
  1922             s.modified.extend(modified2)
  1907             s.deleted.extend(deleted2)
  1923             s.deleted.extend(deleted2)
  1908 
  1924 
       
  1925             if clean_set and clean:
       
  1926                 s.clean.extend(clean_set)
  1909             if fixup and clean:
  1927             if fixup and clean:
  1910                 s.clean.extend((f for f, _ in fixup))
  1928                 s.clean.extend((f for f, _ in fixup))
  1911 
  1929 
  1912         self._poststatusfixup(s, fixup)
  1930         self._poststatusfixup(s, fixup)
  1913 
  1931