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:: |
|
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 |
|
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