##// END OF EJS Templates
dirstate-v2: Drop cached read_dir results after .hgignore changes...
Simon Sapin -
r48268:c657beac default
parent child Browse files
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 = DirstateMap::get_or_insert_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