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