equal
deleted
inserted
replaced
114 self._sparsematchfn = sparsematchfn |
114 self._sparsematchfn = sparsematchfn |
115 # ntpath.join(root, '') of Python 2.7.9 does not add sep if root is |
115 # ntpath.join(root, '') of Python 2.7.9 does not add sep if root is |
116 # UNC path pointing to root share (issue4557) |
116 # UNC path pointing to root share (issue4557) |
117 self._rootdir = pathutil.normasprefix(root) |
117 self._rootdir = pathutil.normasprefix(root) |
118 self._dirty = False |
118 self._dirty = False |
119 self._lastnormaltime = timestamp.zero() |
|
120 self._ui = ui |
119 self._ui = ui |
121 self._filecache = {} |
120 self._filecache = {} |
122 self._parentwriters = 0 |
121 self._parentwriters = 0 |
123 self._filename = b'dirstate' |
122 self._filename = b'dirstate' |
124 self._pendingfilename = b'%s.pending' % self._filename |
123 self._pendingfilename = b'%s.pending' % self._filename |
428 check whether the dirstate has changed before rereading it.""" |
427 check whether the dirstate has changed before rereading it.""" |
429 |
428 |
430 for a in ("_map", "_branch", "_ignore"): |
429 for a in ("_map", "_branch", "_ignore"): |
431 if a in self.__dict__: |
430 if a in self.__dict__: |
432 delattr(self, a) |
431 delattr(self, a) |
433 self._lastnormaltime = timestamp.zero() |
|
434 self._dirty = False |
432 self._dirty = False |
435 self._parentwriters = 0 |
433 self._parentwriters = 0 |
436 self._origpl = None |
434 self._origpl = None |
437 |
435 |
438 def copy(self, source, dest): |
436 def copy(self, source, dest): |
491 self._dirty = True |
489 self._dirty = True |
492 if not self._map[filename].tracked: |
490 if not self._map[filename].tracked: |
493 self._check_new_tracked_filename(filename) |
491 self._check_new_tracked_filename(filename) |
494 (mode, size, mtime) = parentfiledata |
492 (mode, size, mtime) = parentfiledata |
495 self._map.set_clean(filename, mode, size, mtime) |
493 self._map.set_clean(filename, mode, size, mtime) |
496 if mtime > self._lastnormaltime: |
|
497 # Remember the most recent modification timeslot for status(), |
|
498 # to make sure we won't miss future size-preserving file content |
|
499 # modifications that happen within the same timeslot. |
|
500 self._lastnormaltime = mtime |
|
501 |
494 |
502 @requires_no_parents_change |
495 @requires_no_parents_change |
503 def set_possibly_dirty(self, filename): |
496 def set_possibly_dirty(self, filename): |
504 """record that the current state of the file on disk is unknown""" |
497 """record that the current state of the file on disk is unknown""" |
505 self._dirty = True |
498 self._dirty = True |
579 p1_tracked, |
572 p1_tracked, |
580 p2_info=p2_info, |
573 p2_info=p2_info, |
581 has_meaningful_mtime=not possibly_dirty, |
574 has_meaningful_mtime=not possibly_dirty, |
582 parentfiledata=parentfiledata, |
575 parentfiledata=parentfiledata, |
583 ) |
576 ) |
584 if ( |
|
585 parentfiledata is not None |
|
586 and parentfiledata[2] is not None |
|
587 and parentfiledata[2] > self._lastnormaltime |
|
588 ): |
|
589 # Remember the most recent modification timeslot for status(), |
|
590 # to make sure we won't miss future size-preserving file content |
|
591 # modifications that happen within the same timeslot. |
|
592 self._lastnormaltime = parentfiledata[2] |
|
593 |
577 |
594 def _check_new_tracked_filename(self, filename): |
578 def _check_new_tracked_filename(self, filename): |
595 scmutil.checkfilename(filename) |
579 scmutil.checkfilename(filename) |
596 if self._map.hastrackeddir(filename): |
580 if self._map.hastrackeddir(filename): |
597 msg = _(b'directory %r already in dirstate') |
581 msg = _(b'directory %r already in dirstate') |
691 return self._normalize(path, isknown, ignoremissing) |
675 return self._normalize(path, isknown, ignoremissing) |
692 return path |
676 return path |
693 |
677 |
694 def clear(self): |
678 def clear(self): |
695 self._map.clear() |
679 self._map.clear() |
696 self._lastnormaltime = timestamp.zero() |
|
697 self._dirty = True |
680 self._dirty = True |
698 |
681 |
699 def rebuild(self, parent, allfiles, changedfiles=None): |
682 def rebuild(self, parent, allfiles, changedfiles=None): |
700 if changedfiles is None: |
683 if changedfiles is None: |
701 # Rebuild entire dirstate |
684 # Rebuild entire dirstate |
702 to_lookup = allfiles |
685 to_lookup = allfiles |
703 to_drop = [] |
686 to_drop = [] |
704 lastnormaltime = self._lastnormaltime |
|
705 self.clear() |
687 self.clear() |
706 self._lastnormaltime = lastnormaltime |
|
707 elif len(changedfiles) < 10: |
688 elif len(changedfiles) < 10: |
708 # Avoid turning allfiles into a set, which can be expensive if it's |
689 # Avoid turning allfiles into a set, which can be expensive if it's |
709 # large. |
690 # large. |
710 to_lookup = [] |
691 to_lookup = [] |
711 to_drop = [] |
692 to_drop = [] |
816 # trust our estimate that the end is near now |
797 # trust our estimate that the end is near now |
817 now = timestamp.timestamp((end, 0)) |
798 now = timestamp.timestamp((end, 0)) |
818 break |
799 break |
819 |
800 |
820 self._map.write(tr, st, now) |
801 self._map.write(tr, st, now) |
821 self._lastnormaltime = timestamp.zero() |
|
822 self._dirty = False |
802 self._dirty = False |
823 |
803 |
824 def _dirignore(self, f): |
804 def _dirignore(self, f): |
825 if self._ignore(f): |
805 if self._ignore(f): |
826 return True |
806 return True |
1214 self._map._map, |
1194 self._map._map, |
1215 matcher, |
1195 matcher, |
1216 self._rootdir, |
1196 self._rootdir, |
1217 self._ignorefiles(), |
1197 self._ignorefiles(), |
1218 self._checkexec, |
1198 self._checkexec, |
1219 self._lastnormaltime, |
|
1220 bool(list_clean), |
1199 bool(list_clean), |
1221 bool(list_ignored), |
1200 bool(list_ignored), |
1222 bool(list_unknown), |
1201 bool(list_unknown), |
1223 bool(matcher.traversedir), |
1202 bool(matcher.traversedir), |
1224 ) |
1203 ) |
1341 mexact = match.exact |
1320 mexact = match.exact |
1342 dirignore = self._dirignore |
1321 dirignore = self._dirignore |
1343 checkexec = self._checkexec |
1322 checkexec = self._checkexec |
1344 checklink = self._checklink |
1323 checklink = self._checklink |
1345 copymap = self._map.copymap |
1324 copymap = self._map.copymap |
1346 lastnormaltime = self._lastnormaltime |
|
1347 |
1325 |
1348 # We need to do full walks when either |
1326 # We need to do full walks when either |
1349 # - we're listing all clean files, or |
1327 # - we're listing all clean files, or |
1350 # - match.traversedir does something, because match.traversedir should |
1328 # - match.traversedir does something, because match.traversedir should |
1351 # be called for every dir in the working dir |
1329 # be called for every dir in the working dir |
1397 # encryption on EXT-4 fscrypt, undecided. |
1375 # encryption on EXT-4 fscrypt, undecided. |
1398 ladd(fn) |
1376 ladd(fn) |
1399 else: |
1377 else: |
1400 madd(fn) |
1378 madd(fn) |
1401 elif not t.mtime_likely_equal_to(timestamp.mtime_of(st)): |
1379 elif not t.mtime_likely_equal_to(timestamp.mtime_of(st)): |
1402 ladd(fn) |
1380 # There might be a change in the future if for example the |
1403 elif timestamp.mtime_of(st) == lastnormaltime: |
1381 # internal clock is off, but this is a case where the issues |
1404 # fn may have just been marked as normal and it may have |
1382 # the user would face would be a lot worse and there is |
1405 # changed in the same second without changing its size. |
1383 # nothing we can really do. |
1406 # This can happen if we quickly do multiple commits. |
|
1407 # Force lookup, so we don't miss such a racy file change. |
|
1408 ladd(fn) |
1384 ladd(fn) |
1409 elif listclean: |
1385 elif listclean: |
1410 cadd(fn) |
1386 cadd(fn) |
1411 status = scmutil.status( |
1387 status = scmutil.status( |
1412 modified, added, removed, deleted, unknown, ignored, clean |
1388 modified, added, removed, deleted, unknown, ignored, clean |