4 use crate::dirstate_tree::dirstate_map::Node; |
4 use crate::dirstate_tree::dirstate_map::Node; |
5 use crate::matchers::get_ignore_function; |
5 use crate::matchers::get_ignore_function; |
6 use crate::matchers::Matcher; |
6 use crate::matchers::Matcher; |
7 use crate::utils::files::get_bytes_from_os_string; |
7 use crate::utils::files::get_bytes_from_os_string; |
8 use crate::utils::hg_path::HgPath; |
8 use crate::utils::hg_path::HgPath; |
|
9 use crate::BadMatch; |
9 use crate::DirstateStatus; |
10 use crate::DirstateStatus; |
10 use crate::EntryState; |
11 use crate::EntryState; |
11 use crate::HgPathBuf; |
12 use crate::HgPathBuf; |
12 use crate::PatternFileWarning; |
13 use crate::PatternFileWarning; |
13 use crate::StatusError; |
14 use crate::StatusError; |
67 ignore_fn: IgnoreFnType<'a>, |
68 ignore_fn: IgnoreFnType<'a>, |
68 outcome: DirstateStatus<'tree>, |
69 outcome: DirstateStatus<'tree>, |
69 } |
70 } |
70 |
71 |
71 impl<'tree, 'a> StatusCommon<'tree, 'a> { |
72 impl<'tree, 'a> StatusCommon<'tree, 'a> { |
|
73 fn read_dir( |
|
74 &mut self, |
|
75 hg_path: &HgPath, |
|
76 fs_path: &Path, |
|
77 is_at_repo_root: bool, |
|
78 ) -> Result<Vec<DirEntry>, ()> { |
|
79 DirEntry::read_dir(fs_path, is_at_repo_root).map_err(|error| { |
|
80 let errno = error.raw_os_error().expect("expected real OS error"); |
|
81 self.outcome |
|
82 .bad |
|
83 .push((hg_path.to_owned().into(), BadMatch::OsError(errno))) |
|
84 }) |
|
85 } |
|
86 |
72 fn traverse_fs_directory_and_dirstate( |
87 fn traverse_fs_directory_and_dirstate( |
73 &mut self, |
88 &mut self, |
74 has_ignored_ancestor: bool, |
89 has_ignored_ancestor: bool, |
75 dirstate_nodes: &'tree mut ChildNodes, |
90 dirstate_nodes: &'tree mut ChildNodes, |
76 directory_hg_path: &HgPath, |
91 directory_hg_path: &'tree HgPath, |
77 fs_path: &Path, |
92 directory_fs_path: &Path, |
78 is_at_repo_root: bool, |
93 is_at_repo_root: bool, |
79 ) { |
94 ) { |
80 // TODO: handle I/O errors |
95 let mut fs_entries = if let Ok(entries) = self.read_dir( |
81 let mut fs_entries = |
96 directory_hg_path, |
82 DirEntry::read_dir(fs_path, is_at_repo_root).unwrap(); |
97 directory_fs_path, |
|
98 is_at_repo_root, |
|
99 ) { |
|
100 entries |
|
101 } else { |
|
102 return; |
|
103 }; |
83 |
104 |
84 // `merge_join_by` requires both its input iterators to be sorted: |
105 // `merge_join_by` requires both its input iterators to be sorted: |
85 |
106 |
86 // * `BTreeMap` iterates according to keys’ ordering by definition |
107 // * `BTreeMap` iterates according to keys’ ordering by definition |
87 |
108 |
293 // ignored |
314 // ignored |
294 self.options.list_unknown || self.options.list_ignored |
315 self.options.list_unknown || self.options.list_ignored |
295 }; |
316 }; |
296 if traverse_children { |
317 if traverse_children { |
297 let is_at_repo_root = false; |
318 let is_at_repo_root = false; |
298 // TODO: handle I/O errors |
319 if let Ok(children_fs_entries) = self.read_dir( |
299 let children_fs_entries = |
320 &hg_path, |
300 DirEntry::read_dir(&fs_entry.full_path, is_at_repo_root) |
321 &fs_entry.full_path, |
301 .unwrap(); |
322 is_at_repo_root, |
302 for child_fs_entry in children_fs_entries { |
323 ) { |
303 self.traverse_fs_only( |
324 for child_fs_entry in children_fs_entries { |
304 is_ignored, |
325 self.traverse_fs_only( |
305 &hg_path, |
326 is_ignored, |
306 &child_fs_entry, |
327 &hg_path, |
307 ) |
328 &child_fs_entry, |
|
329 ) |
|
330 } |
308 } |
331 } |
309 } |
332 } |
310 if self.options.collect_traversed_dirs { |
333 if self.options.collect_traversed_dirs { |
311 self.outcome.traversed.push(hg_path.into()) |
334 self.outcome.traversed.push(hg_path.into()) |
312 } |
335 } |