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 |