##// END OF EJS Templates
dirstate: remove `lastnormaltime` mechanism...
Raphaël Gomès -
r49214:a19d1225 default draft
parent child Browse files
Show More
@@ -116,7 +116,6 b' class dirstate(object):'
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
@@ -430,7 +429,6 b' class dirstate(object):'
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
@@ -493,11 +491,6 b' class dirstate(object):'
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):
@@ -581,15 +574,6 b' class dirstate(object):'
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)
@@ -693,7 +677,6 b' class dirstate(object):'
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):
@@ -701,9 +684,7 b' class dirstate(object):'
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.
@@ -818,7 +799,6 b' class dirstate(object):'
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):
@@ -1216,7 +1196,6 b' class dirstate(object):'
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),
@@ -1343,7 +1322,6 b' class dirstate(object):'
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
@@ -1399,12 +1377,10 b' class dirstate(object):'
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)
@@ -12,7 +12,6 b''
12 use crate::dirstate_tree::on_disk::DirstateV2ParseError;
12 use crate::dirstate_tree::on_disk::DirstateV2ParseError;
13
13
14 use crate::{
14 use crate::{
15 dirstate::TruncatedTimestamp,
16 utils::hg_path::{HgPath, HgPathError},
15 utils::hg_path::{HgPath, HgPathError},
17 PatternError,
16 PatternError,
18 };
17 };
@@ -62,10 +61,6 b" pub type HgPathCow<'a> = Cow<'a, HgPath>"
62
61
63 #[derive(Debug, Copy, Clone)]
62 #[derive(Debug, Copy, Clone)]
64 pub struct StatusOptions {
63 pub struct StatusOptions {
65 /// Remember the most recent modification timeslot for status, to make
66 /// sure we won't miss future size-preserving file content modifications
67 /// that happen within the same timeslot.
68 pub last_normal_time: TruncatedTimestamp,
69 /// Whether we are on a filesystem with UNIX-like exec flags
64 /// Whether we are on a filesystem with UNIX-like exec flags
70 pub check_exec: bool,
65 pub check_exec: bool,
71 pub list_clean: bool,
66 pub list_clean: bool,
@@ -532,8 +532,12 b" impl<'a, 'tree, 'on_disk> StatusCommon<'"
532 if let Some(dirstate_mtime) = entry.truncated_mtime() {
532 if let Some(dirstate_mtime) = entry.truncated_mtime() {
533 let fs_mtime = TruncatedTimestamp::for_mtime_of(fs_metadata)
533 let fs_mtime = TruncatedTimestamp::for_mtime_of(fs_metadata)
534 .expect("OS/libc does not support mtime?");
534 .expect("OS/libc does not support mtime?");
535 // There might be a change in the future if for example the
536 // internal clock become off while process run, but this is a
537 // case where the issues the user would face
538 // would be a lot worse and there is nothing we
539 // can really do.
535 mtime_looks_clean = fs_mtime.likely_equal(dirstate_mtime)
540 mtime_looks_clean = fs_mtime.likely_equal(dirstate_mtime)
536 && !fs_mtime.likely_equal(self.options.last_normal_time)
537 } else {
541 } else {
538 // No mtime in the dirstate entry
542 // No mtime in the dirstate entry
539 mtime_looks_clean = false
543 mtime_looks_clean = false
@@ -54,7 +54,6 b' pub fn init_module(py: Python, package: '
54 matcher: PyObject,
54 matcher: PyObject,
55 ignorefiles: PyList,
55 ignorefiles: PyList,
56 check_exec: bool,
56 check_exec: bool,
57 last_normal_time: (u32, u32),
58 list_clean: bool,
57 list_clean: bool,
59 list_ignored: bool,
58 list_ignored: bool,
60 list_unknown: bool,
59 list_unknown: bool,
@@ -9,7 +9,6 b''
9 //! `hg-core` crate. From Python, this will be seen as
9 //! `hg-core` crate. From Python, this will be seen as
10 //! `rustext.dirstate.status`.
10 //! `rustext.dirstate.status`.
11
11
12 use crate::dirstate::item::timestamp;
13 use crate::{dirstate::DirstateMap, exceptions::FallbackError};
12 use crate::{dirstate::DirstateMap, exceptions::FallbackError};
14 use cpython::exc::OSError;
13 use cpython::exc::OSError;
15 use cpython::{
14 use cpython::{
@@ -103,13 +102,11 b' pub fn status_wrapper('
103 root_dir: PyObject,
102 root_dir: PyObject,
104 ignore_files: PyList,
103 ignore_files: PyList,
105 check_exec: bool,
104 check_exec: bool,
106 last_normal_time: (u32, u32),
107 list_clean: bool,
105 list_clean: bool,
108 list_ignored: bool,
106 list_ignored: bool,
109 list_unknown: bool,
107 list_unknown: bool,
110 collect_traversed_dirs: bool,
108 collect_traversed_dirs: bool,
111 ) -> PyResult<PyTuple> {
109 ) -> PyResult<PyTuple> {
112 let last_normal_time = timestamp(py, last_normal_time)?;
113 let bytes = root_dir.extract::<PyBytes>(py)?;
110 let bytes = root_dir.extract::<PyBytes>(py)?;
114 let root_dir = get_path_from_bytes(bytes.data(py));
111 let root_dir = get_path_from_bytes(bytes.data(py));
115
112
@@ -135,7 +132,6 b' pub fn status_wrapper('
135 ignore_files,
132 ignore_files,
136 StatusOptions {
133 StatusOptions {
137 check_exec,
134 check_exec,
138 last_normal_time,
139 list_clean,
135 list_clean,
140 list_ignored,
136 list_ignored,
141 list_unknown,
137 list_unknown,
@@ -172,7 +168,6 b' pub fn status_wrapper('
172 ignore_files,
168 ignore_files,
173 StatusOptions {
169 StatusOptions {
174 check_exec,
170 check_exec,
175 last_normal_time,
176 list_clean,
171 list_clean,
177 list_ignored,
172 list_ignored,
178 list_unknown,
173 list_unknown,
@@ -224,7 +219,6 b' pub fn status_wrapper('
224 ignore_files,
219 ignore_files,
225 StatusOptions {
220 StatusOptions {
226 check_exec,
221 check_exec,
227 last_normal_time,
228 list_clean,
222 list_clean,
229 list_ignored,
223 list_ignored,
230 list_unknown,
224 list_unknown,
@@ -12,7 +12,7 b' use clap::{Arg, SubCommand};'
12 use format_bytes::format_bytes;
12 use format_bytes::format_bytes;
13 use hg;
13 use hg;
14 use hg::config::Config;
14 use hg::config::Config;
15 use hg::dirstate::{has_exec_bit, TruncatedTimestamp};
15 use hg::dirstate::has_exec_bit;
16 use hg::errors::HgError;
16 use hg::errors::HgError;
17 use hg::manifest::Manifest;
17 use hg::manifest::Manifest;
18 use hg::matchers::AlwaysMatcher;
18 use hg::matchers::AlwaysMatcher;
@@ -194,11 +194,6 b' pub fn run(invocation: &crate::CliInvoca'
194 let mut dmap = repo.dirstate_map_mut()?;
194 let mut dmap = repo.dirstate_map_mut()?;
195
195
196 let options = StatusOptions {
196 let options = StatusOptions {
197 // TODO should be provided by the dirstate parsing and
198 // hence be stored on dmap. Using a value that assumes we aren't
199 // below the time resolution granularity of the FS and the
200 // dirstate.
201 last_normal_time: TruncatedTimestamp::new_truncate(0, 0),
202 // we're currently supporting file systems with exec flags only
197 // we're currently supporting file systems with exec flags only
203 // anyway
198 // anyway
204 check_exec: true,
199 check_exec: true,
@@ -369,7 +364,8 b' fn unsure_is_modified('
369 let fs_path = hg_path_to_os_string(hg_path).expect("HgPath conversion");
364 let fs_path = hg_path_to_os_string(hg_path).expect("HgPath conversion");
370 let fs_metadata = vfs.symlink_metadata(&fs_path)?;
365 let fs_metadata = vfs.symlink_metadata(&fs_path)?;
371 let is_symlink = fs_metadata.file_type().is_symlink();
366 let is_symlink = fs_metadata.file_type().is_symlink();
372 // TODO: Also account for `FALLBACK_SYMLINK` and `FALLBACK_EXEC` from the dirstate
367 // TODO: Also account for `FALLBACK_SYMLINK` and `FALLBACK_EXEC` from the
368 // dirstate
373 let fs_flags = if is_symlink {
369 let fs_flags = if is_symlink {
374 Some(b'l')
370 Some(b'l')
375 } else if has_exec_bit(&fs_metadata) {
371 } else if has_exec_bit(&fs_metadata) {
General Comments 0
You need to be logged in to leave comments. Login now