Mercurial > hg
changeset 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 | 9172bd49cedc |
files | rust/hg-core/src/dirstate_tree/status.rs tests/test-status.t |
diffstat | 2 files changed, 22 insertions(+), 20 deletions(-) [+] |
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)?
--- a/tests/test-status.t Wed Oct 19 15:11:05 2022 +0200 +++ b/tests/test-status.t Wed Oct 19 16:28:41 2022 +0200 @@ -993,16 +993,8 @@ $ hg status ? another-subdir/something-else - $ hg debugdirstate --all --no-dates | grep '^ ' - 0 -1 unset subdir (known-bad-output !) - -For some reason the first [status] is not enough to save the updated -directory mtime into the cache. The second invocation does it. -The first call only clears the directory cache by marking the directories -as "outdated", which seems like a bug. - - $ hg status - ? another-subdir/something-else +One invocation of status is enough to populate the cache even if it's invalidated +in the same run. $ hg debugdirstate --all --no-dates | grep '^ ' 0 -1 set subdir