Show More
@@ -83,9 +83,7 b' fn dispatch_found(' | |||||
83 | entry: DirstateEntry, |
|
83 | entry: DirstateEntry, | |
84 | metadata: HgMetadata, |
|
84 | metadata: HgMetadata, | |
85 | copy_map: &CopyMap, |
|
85 | copy_map: &CopyMap, | |
86 | check_exec: bool, |
|
86 | options: StatusOptions, | |
87 | list_clean: bool, |
|
|||
88 | last_normal_time: i64, |
|
|||
89 | ) -> Dispatch { |
|
87 | ) -> Dispatch { | |
90 | let DirstateEntry { |
|
88 | let DirstateEntry { | |
91 | state, |
|
89 | state, | |
@@ -105,7 +103,7 b' fn dispatch_found(' | |||||
105 | EntryState::Normal => { |
|
103 | EntryState::Normal => { | |
106 | let size_changed = mod_compare(size, st_size as i32); |
|
104 | let size_changed = mod_compare(size, st_size as i32); | |
107 | let mode_changed = |
|
105 | let mode_changed = | |
108 | (mode ^ st_mode as i32) & 0o100 != 0o000 && check_exec; |
|
106 | (mode ^ st_mode as i32) & 0o100 != 0o000 && options.check_exec; | |
109 | let metadata_changed = size >= 0 && (size_changed || mode_changed); |
|
107 | let metadata_changed = size >= 0 && (size_changed || mode_changed); | |
110 | let other_parent = size == SIZE_FROM_OTHER_PARENT; |
|
108 | let other_parent = size == SIZE_FROM_OTHER_PARENT; | |
111 | if metadata_changed |
|
109 | if metadata_changed | |
@@ -115,14 +113,14 b' fn dispatch_found(' | |||||
115 | Dispatch::Modified |
|
113 | Dispatch::Modified | |
116 | } else if mod_compare(mtime, st_mtime as i32) { |
|
114 | } else if mod_compare(mtime, st_mtime as i32) { | |
117 | Dispatch::Unsure |
|
115 | Dispatch::Unsure | |
118 | } else if st_mtime == last_normal_time { |
|
116 | } else if st_mtime == options.last_normal_time { | |
119 | // the file may have just been marked as normal and |
|
117 | // the file may have just been marked as normal and | |
120 | // it may have changed in the same second without |
|
118 | // it may have changed in the same second without | |
121 | // changing its size. This can happen if we quickly |
|
119 | // changing its size. This can happen if we quickly | |
122 | // do multiple commits. Force lookup, so we don't |
|
120 | // do multiple commits. Force lookup, so we don't | |
123 | // miss such a racy file change. |
|
121 | // miss such a racy file change. | |
124 | Dispatch::Unsure |
|
122 | Dispatch::Unsure | |
125 | } else if list_clean { |
|
123 | } else if options.list_clean { | |
126 | Dispatch::Clean |
|
124 | Dispatch::Clean | |
127 | } else { |
|
125 | } else { | |
128 | Dispatch::Unknown |
|
126 | Dispatch::Unknown | |
@@ -155,9 +153,7 b" fn walk_explicit<'a>(" | |||||
155 | files: &'a HashSet<&HgPath>, |
|
153 | files: &'a HashSet<&HgPath>, | |
156 | dmap: &'a DirstateMap, |
|
154 | dmap: &'a DirstateMap, | |
157 | root_dir: impl AsRef<Path> + Sync + Send, |
|
155 | root_dir: impl AsRef<Path> + Sync + Send, | |
158 | check_exec: bool, |
|
156 | options: StatusOptions, | |
159 | list_clean: bool, |
|
|||
160 | last_normal_time: i64, |
|
|||
161 | ) -> impl ParallelIterator<Item = IoResult<(&'a HgPath, Dispatch)>> { |
|
157 | ) -> impl ParallelIterator<Item = IoResult<(&'a HgPath, Dispatch)>> { | |
162 | files.par_iter().filter_map(move |filename| { |
|
158 | files.par_iter().filter_map(move |filename| { | |
163 | // TODO normalization |
|
159 | // TODO normalization | |
@@ -181,9 +177,7 b" fn walk_explicit<'a>(" | |||||
181 | *entry, |
|
177 | *entry, | |
182 | HgMetadata::from_metadata(meta), |
|
178 | HgMetadata::from_metadata(meta), | |
183 | &dmap.copy_map, |
|
179 | &dmap.copy_map, | |
184 |
|
|
180 | options, | |
185 | list_clean, |
|
|||
186 | last_normal_time, |
|
|||
187 | ), |
|
181 | ), | |
188 | ))); |
|
182 | ))); | |
189 | } |
|
183 | } | |
@@ -206,14 +200,23 b" fn walk_explicit<'a>(" | |||||
206 | }) |
|
200 | }) | |
207 | } |
|
201 | } | |
208 |
|
202 | |||
|
203 | #[derive(Debug, Copy, Clone)] | |||
|
204 | pub struct StatusOptions { | |||
|
205 | /// Remember the most recent modification timeslot for status, to make | |||
|
206 | /// sure we won't miss future size-preserving file content modifications | |||
|
207 | /// that happen within the same timeslot. | |||
|
208 | pub last_normal_time: i64, | |||
|
209 | /// Whether we are on a filesystem with UNIX-like exec flags | |||
|
210 | pub check_exec: bool, | |||
|
211 | pub list_clean: bool, | |||
|
212 | } | |||
|
213 | ||||
209 | /// Stat all entries in the `DirstateMap` and mark them for dispatch into |
|
214 | /// Stat all entries in the `DirstateMap` and mark them for dispatch into | |
210 | /// the relevant collections. |
|
215 | /// the relevant collections. | |
211 | fn stat_dmap_entries( |
|
216 | fn stat_dmap_entries( | |
212 | dmap: &DirstateMap, |
|
217 | dmap: &DirstateMap, | |
213 | root_dir: impl AsRef<Path> + Sync + Send, |
|
218 | root_dir: impl AsRef<Path> + Sync + Send, | |
214 | check_exec: bool, |
|
219 | options: StatusOptions, | |
215 | list_clean: bool, |
|
|||
216 | last_normal_time: i64, |
|
|||
217 | ) -> impl ParallelIterator<Item = IoResult<(&HgPath, Dispatch)>> { |
|
220 | ) -> impl ParallelIterator<Item = IoResult<(&HgPath, Dispatch)>> { | |
218 | dmap.par_iter().map(move |(filename, entry)| { |
|
221 | dmap.par_iter().map(move |(filename, entry)| { | |
219 | let filename: &HgPath = filename; |
|
222 | let filename: &HgPath = filename; | |
@@ -234,9 +237,7 b' fn stat_dmap_entries(' | |||||
234 | *entry, |
|
237 | *entry, | |
235 | HgMetadata::from_metadata(m), |
|
238 | HgMetadata::from_metadata(m), | |
236 | &dmap.copy_map, |
|
239 | &dmap.copy_map, | |
237 |
|
|
240 | options, | |
238 | list_clean, |
|
|||
239 | last_normal_time, |
|
|||
240 | ), |
|
241 | ), | |
241 | )), |
|
242 | )), | |
242 | Err(ref e) |
|
243 | Err(ref e) | |
@@ -303,31 +304,16 b" pub fn status<'a: 'c, 'b: 'c, 'c>(" | |||||
303 | dmap: &'a DirstateMap, |
|
304 | dmap: &'a DirstateMap, | |
304 | matcher: &'b impl Matcher, |
|
305 | matcher: &'b impl Matcher, | |
305 | root_dir: impl AsRef<Path> + Sync + Send + Copy, |
|
306 | root_dir: impl AsRef<Path> + Sync + Send + Copy, | |
306 | list_clean: bool, |
|
307 | options: StatusOptions, | |
307 | last_normal_time: i64, |
|
|||
308 | check_exec: bool, |
|
|||
309 | ) -> IoResult<(Vec<&'c HgPath>, StatusResult<'c>)> { |
|
308 | ) -> IoResult<(Vec<&'c HgPath>, StatusResult<'c>)> { | |
310 | let files = matcher.file_set(); |
|
309 | let files = matcher.file_set(); | |
311 | let mut results = vec![]; |
|
310 | let mut results = vec![]; | |
312 | if let Some(files) = files { |
|
311 | if let Some(files) = files { | |
313 | results.par_extend(walk_explicit( |
|
312 | results.par_extend(walk_explicit(&files, &dmap, root_dir, options)); | |
314 | &files, |
|
|||
315 | &dmap, |
|
|||
316 | root_dir, |
|
|||
317 | check_exec, |
|
|||
318 | list_clean, |
|
|||
319 | last_normal_time, |
|
|||
320 | )); |
|
|||
321 | } |
|
313 | } | |
322 |
|
314 | |||
323 | if !matcher.is_exact() { |
|
315 | if !matcher.is_exact() { | |
324 | let stat_results = stat_dmap_entries( |
|
316 | let stat_results = stat_dmap_entries(&dmap, root_dir, options); | |
325 | &dmap, |
|
|||
326 | root_dir, |
|
|||
327 | check_exec, |
|
|||
328 | list_clean, |
|
|||
329 | last_normal_time, |
|
|||
330 | ); |
|
|||
331 | results.par_extend(stat_results); |
|
317 | results.par_extend(stat_results); | |
332 | } |
|
318 | } | |
333 |
|
319 |
@@ -13,7 +13,7 b' pub use dirstate::{' | |||||
13 | dirs_multiset::{DirsMultiset, DirsMultisetIter}, |
|
13 | dirs_multiset::{DirsMultiset, DirsMultisetIter}, | |
14 | dirstate_map::DirstateMap, |
|
14 | dirstate_map::DirstateMap, | |
15 | parsers::{pack_dirstate, parse_dirstate, PARENT_SIZE}, |
|
15 | parsers::{pack_dirstate, parse_dirstate, PARENT_SIZE}, | |
16 | status::{status, StatusResult}, |
|
16 | status::{status, StatusOptions, StatusResult}, | |
17 | CopyMap, CopyMapIter, DirstateEntry, DirstateParents, EntryState, |
|
17 | CopyMap, CopyMapIter, DirstateEntry, DirstateParents, EntryState, | |
18 | StateMap, StateMapIter, |
|
18 | StateMap, StateMapIter, | |
19 | }; |
|
19 | }; |
@@ -668,7 +668,11 b' mod tests {' | |||||
668 |
|
668 | |||
669 | assert_eq!( |
|
669 | assert_eq!( | |
670 | roots_dirs_and_parents(&pats).unwrap(), |
|
670 | roots_dirs_and_parents(&pats).unwrap(), | |
671 |
RootsDirsAndParents { |
|
671 | RootsDirsAndParents { | |
|
672 | roots, | |||
|
673 | dirs, | |||
|
674 | parents | |||
|
675 | } | |||
672 | ); |
|
676 | ); | |
673 | } |
|
677 | } | |
674 |
|
678 |
General Comments 0
You need to be logged in to leave comments.
Login now