Mercurial > public > mercurial-scm > hg
diff rust/hg-core/src/dirstate_tree/status.rs @ 49555:8ee3889bab92 stable
rust-status: save new dircache even if just invalidated
There was a functional race between invalidating the cache (not acted upon
until the end of the status algorithm) and populating the new cache (which
relies upon an up-to-date version of the cache).
We simply inform the cache populating function that we've just invalidated
the cache for this particular directory since the information is present in
the same scope.
author | Rapha?l Gom?s <rgomes@octobus.net> |
---|---|
date | Wed, 19 Oct 2022 16:28:41 +0200 |
parents | ecf9788cd9c4 |
children | 363923bd51cd |
line wrap: on
line diff
--- a/rust/hg-core/src/dirstate_tree/status.rs Wed Oct 19 15:11:05 2022 +0200 +++ b/rust/hg-core/src/dirstate_tree/status.rs Wed Oct 19 16:28:41 2022 +0200 @@ -303,7 +303,7 @@ fn check_for_outdated_directory_cache( &self, dirstate_node: &NodeRef<'tree, 'on_disk>, - ) -> Result<(), DirstateV2ParseError> { + ) -> Result<bool, DirstateV2ParseError> { if self.ignore_patterns_have_changed == Some(true) && dirstate_node.cached_directory_mtime()?.is_some() { @@ -311,9 +311,10 @@ dirstate_node .full_path_borrowed(self.dmap.on_disk)? .detach_from_tree(), - ) + ); + return Ok(true); } - Ok(()) + Ok(false) } /// If this returns true, we can get accurate results by only using @@ -473,7 +474,8 @@ dirstate_node: NodeRef<'tree, 'on_disk>, has_ignored_ancestor: &'ancestor HasIgnoredAncestor<'ancestor>, ) -> Result<(), DirstateV2ParseError> { - self.check_for_outdated_directory_cache(&dirstate_node)?; + let outdated_dircache = + self.check_for_outdated_directory_cache(&dirstate_node)?; let hg_path = &dirstate_node.full_path_borrowed(self.dmap.on_disk)?; let file_type = fs_metadata.file_type(); let file_or_symlink = file_type.is_file() || file_type.is_symlink(); @@ -510,6 +512,7 @@ children_all_have_dirstate_node_or_are_ignored, fs_metadata, dirstate_node, + outdated_dircache, )? } else { if file_or_symlink && self.matcher.matches(&hg_path) { @@ -549,11 +552,17 @@ Ok(()) } + /// Save directory mtime if applicable. + /// + /// `outdated_directory_cache` is `true` if we've just invalidated the + /// cache for this directory in `check_for_outdated_directory_cache`, + /// which forces the update. fn maybe_save_directory_mtime( &self, children_all_have_dirstate_node_or_are_ignored: bool, directory_metadata: &std::fs::Metadata, dirstate_node: NodeRef<'tree, 'on_disk>, + outdated_directory_cache: bool, ) -> Result<(), DirstateV2ParseError> { if !children_all_have_dirstate_node_or_are_ignored { return Ok(()); @@ -621,12 +630,13 @@ // We deem this scenario (unlike the previous one) to be // unlikely enough in practice. - let is_up_to_date = - if let Some(cached) = dirstate_node.cached_directory_mtime()? { - cached.likely_equal(directory_mtime) - } else { - false - }; + let is_up_to_date = if let Some(cached) = + dirstate_node.cached_directory_mtime()? + { + !outdated_directory_cache && cached.likely_equal(directory_mtime) + } else { + false + }; if !is_up_to_date { let hg_path = dirstate_node .full_path_borrowed(self.dmap.on_disk)?