Show More
@@ -495,6 +495,19 b" impl<'on_disk> DirstateMap<'on_disk> {" | |||||
495 | } |
|
495 | } | |
496 | } |
|
496 | } | |
497 |
|
497 | |||
|
498 | pub(super) fn get_or_insert<'tree, 'path>( | |||
|
499 | &'tree mut self, | |||
|
500 | path: &HgPath, | |||
|
501 | ) -> Result<&'tree mut Node<'on_disk>, DirstateV2ParseError> { | |||
|
502 | Self::get_or_insert_node( | |||
|
503 | self.on_disk, | |||
|
504 | &mut self.root, | |||
|
505 | path, | |||
|
506 | WithBasename::to_cow_owned, | |||
|
507 | |_| {}, | |||
|
508 | ) | |||
|
509 | } | |||
|
510 | ||||
498 | pub(super) fn get_or_insert_node<'tree, 'path>( |
|
511 | pub(super) fn get_or_insert_node<'tree, 'path>( | |
499 | on_disk: &'on_disk [u8], |
|
512 | on_disk: &'on_disk [u8], | |
500 | root: &'tree mut ChildNodes<'on_disk>, |
|
513 | root: &'tree mut ChildNodes<'on_disk>, |
@@ -6,7 +6,6 b' use crate::dirstate_tree::dirstate_map::' | |||||
6 | use crate::dirstate_tree::dirstate_map::NodeRef; |
|
6 | use crate::dirstate_tree::dirstate_map::NodeRef; | |
7 | use crate::dirstate_tree::on_disk::DirstateV2ParseError; |
|
7 | use crate::dirstate_tree::on_disk::DirstateV2ParseError; | |
8 | use crate::dirstate_tree::on_disk::Timestamp; |
|
8 | use crate::dirstate_tree::on_disk::Timestamp; | |
9 | use crate::dirstate_tree::path_with_basename::WithBasename; |
|
|||
10 | use crate::matchers::get_ignore_function; |
|
9 | use crate::matchers::get_ignore_function; | |
11 | use crate::matchers::Matcher; |
|
10 | use crate::matchers::Matcher; | |
12 | use crate::utils::files::get_bytes_from_os_string; |
|
11 | use crate::utils::files::get_bytes_from_os_string; | |
@@ -70,6 +69,7 b" pub fn status<'tree, 'on_disk: 'tree>(" | |||||
70 | outcome: Default::default(), |
|
69 | outcome: Default::default(), | |
71 | ignore_patterns_have_changed: patterns_changed, |
|
70 | ignore_patterns_have_changed: patterns_changed, | |
72 | new_cachable_directories: Default::default(), |
|
71 | new_cachable_directories: Default::default(), | |
|
72 | outated_cached_directories: Default::default(), | |||
73 | filesystem_time_at_status_start: filesystem_now(&root_dir).ok(), |
|
73 | filesystem_time_at_status_start: filesystem_now(&root_dir).ok(), | |
74 | }; |
|
74 | }; | |
75 | let is_at_repo_root = true; |
|
75 | let is_at_repo_root = true; | |
@@ -91,18 +91,22 b" pub fn status<'tree, 'on_disk: 'tree>(" | |||||
91 | )?; |
|
91 | )?; | |
92 | let mut outcome = common.outcome.into_inner().unwrap(); |
|
92 | let mut outcome = common.outcome.into_inner().unwrap(); | |
93 | let new_cachable = common.new_cachable_directories.into_inner().unwrap(); |
|
93 | let new_cachable = common.new_cachable_directories.into_inner().unwrap(); | |
|
94 | let outdated = common.outated_cached_directories.into_inner().unwrap(); | |||
94 |
|
95 | |||
95 | outcome.dirty = common.ignore_patterns_have_changed == Some(true) |
|
96 | outcome.dirty = common.ignore_patterns_have_changed == Some(true) | |
|
97 | || !outdated.is_empty() | |||
96 | || !new_cachable.is_empty(); |
|
98 | || !new_cachable.is_empty(); | |
97 |
|
99 | |||
|
100 | // Remove outdated mtimes before adding new mtimes, in case a given | |||
|
101 | // directory is both | |||
|
102 | for path in &outdated { | |||
|
103 | let node = dmap.get_or_insert(path)?; | |||
|
104 | if let NodeData::CachedDirectory { .. } = &node.data { | |||
|
105 | node.data = NodeData::None | |||
|
106 | } | |||
|
107 | } | |||
98 | for (path, mtime) in &new_cachable { |
|
108 | for (path, mtime) in &new_cachable { | |
99 |
let node = |
|
109 | let node = dmap.get_or_insert(path)?; | |
100 | dmap.on_disk, |
|
|||
101 | &mut dmap.root, |
|
|||
102 | path, |
|
|||
103 | WithBasename::to_cow_owned, |
|
|||
104 | |_| {}, |
|
|||
105 | )?; |
|
|||
106 | match &node.data { |
|
110 | match &node.data { | |
107 | NodeData::Entry(_) => {} // Don’t overwrite an entry |
|
111 | NodeData::Entry(_) => {} // Don’t overwrite an entry | |
108 | NodeData::CachedDirectory { .. } | NodeData::None => { |
|
112 | NodeData::CachedDirectory { .. } | NodeData::None => { | |
@@ -123,6 +127,7 b" struct StatusCommon<'a, 'tree, 'on_disk:" | |||||
123 | ignore_fn: IgnoreFnType<'a>, |
|
127 | ignore_fn: IgnoreFnType<'a>, | |
124 | outcome: Mutex<DirstateStatus<'on_disk>>, |
|
128 | outcome: Mutex<DirstateStatus<'on_disk>>, | |
125 | new_cachable_directories: Mutex<Vec<(Cow<'on_disk, HgPath>, Timestamp)>>, |
|
129 | new_cachable_directories: Mutex<Vec<(Cow<'on_disk, HgPath>, Timestamp)>>, | |
|
130 | outated_cached_directories: Mutex<Vec<Cow<'on_disk, HgPath>>>, | |||
126 |
|
131 | |||
127 | /// Whether ignore files like `.hgignore` have changed since the previous |
|
132 | /// Whether ignore files like `.hgignore` have changed since the previous | |
128 | /// time a `status()` call wrote their hash to the dirstate. `None` means |
|
133 | /// time a `status()` call wrote their hash to the dirstate. `None` means | |
@@ -155,6 +160,22 b" impl<'a, 'tree, 'on_disk> StatusCommon<'" | |||||
155 | .push((hg_path.to_owned().into(), BadMatch::OsError(errno))) |
|
160 | .push((hg_path.to_owned().into(), BadMatch::OsError(errno))) | |
156 | } |
|
161 | } | |
157 |
|
162 | |||
|
163 | fn check_for_outdated_directory_cache( | |||
|
164 | &self, | |||
|
165 | dirstate_node: &NodeRef<'tree, 'on_disk>, | |||
|
166 | ) -> Result<(), DirstateV2ParseError> { | |||
|
167 | if self.ignore_patterns_have_changed == Some(true) | |||
|
168 | && dirstate_node.cached_directory_mtime().is_some() | |||
|
169 | { | |||
|
170 | self.outated_cached_directories.lock().unwrap().push( | |||
|
171 | dirstate_node | |||
|
172 | .full_path_borrowed(self.dmap.on_disk)? | |||
|
173 | .detach_from_tree(), | |||
|
174 | ) | |||
|
175 | } | |||
|
176 | Ok(()) | |||
|
177 | } | |||
|
178 | ||||
158 | /// If this returns true, we can get accurate results by only using |
|
179 | /// If this returns true, we can get accurate results by only using | |
159 | /// `symlink_metadata` for child nodes that exist in the dirstate and don’t |
|
180 | /// `symlink_metadata` for child nodes that exist in the dirstate and don’t | |
160 | /// need to call `read_dir`. |
|
181 | /// need to call `read_dir`. | |
@@ -304,6 +325,7 b" impl<'a, 'tree, 'on_disk> StatusCommon<'" | |||||
304 | dirstate_node: NodeRef<'tree, 'on_disk>, |
|
325 | dirstate_node: NodeRef<'tree, 'on_disk>, | |
305 | has_ignored_ancestor: bool, |
|
326 | has_ignored_ancestor: bool, | |
306 | ) -> Result<(), DirstateV2ParseError> { |
|
327 | ) -> Result<(), DirstateV2ParseError> { | |
|
328 | self.check_for_outdated_directory_cache(&dirstate_node)?; | |||
307 | let hg_path = &dirstate_node.full_path_borrowed(self.dmap.on_disk)?; |
|
329 | let hg_path = &dirstate_node.full_path_borrowed(self.dmap.on_disk)?; | |
308 | let file_type = fs_metadata.file_type(); |
|
330 | let file_type = fs_metadata.file_type(); | |
309 | let file_or_symlink = file_type.is_file() || file_type.is_symlink(); |
|
331 | let file_or_symlink = file_type.is_file() || file_type.is_symlink(); | |
@@ -521,6 +543,7 b" impl<'a, 'tree, 'on_disk> StatusCommon<'" | |||||
521 | &self, |
|
543 | &self, | |
522 | dirstate_node: NodeRef<'tree, 'on_disk>, |
|
544 | dirstate_node: NodeRef<'tree, 'on_disk>, | |
523 | ) -> Result<(), DirstateV2ParseError> { |
|
545 | ) -> Result<(), DirstateV2ParseError> { | |
|
546 | self.check_for_outdated_directory_cache(&dirstate_node)?; | |||
524 | self.mark_removed_or_deleted_if_file( |
|
547 | self.mark_removed_or_deleted_if_file( | |
525 | &dirstate_node.full_path_borrowed(self.dmap.on_disk)?, |
|
548 | &dirstate_node.full_path_borrowed(self.dmap.on_disk)?, | |
526 | dirstate_node.state()?, |
|
549 | dirstate_node.state()?, |
General Comments 0
You need to be logged in to leave comments.
Login now