diff --git a/rust/hg-core/src/dirstate_tree/status.rs b/rust/hg-core/src/dirstate_tree/status.rs index ecf9788cd9c409b5d835218c5b3de3fef7d0e287_cnVzdC9oZy1jb3JlL3NyYy9kaXJzdGF0ZV90cmVlL3N0YXR1cy5ycw==..8ee3889bab927284e2ebb5ad75eb943f40e2fd5f_cnVzdC9oZy1jb3JlL3NyYy9kaXJzdGF0ZV90cmVlL3N0YXR1cy5ycw== 100644 --- a/rust/hg-core/src/dirstate_tree/status.rs +++ b/rust/hg-core/src/dirstate_tree/status.rs @@ -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,5 +311,6 @@ dirstate_node .full_path_borrowed(self.dmap.on_disk)? .detach_from_tree(), - ) + ); + return Ok(true); } @@ -315,5 +316,5 @@ } - 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,8 +552,13 @@ 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>, @@ -552,8 +560,9 @@ 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)? diff --git a/tests/test-status.t b/tests/test-status.t index ecf9788cd9c409b5d835218c5b3de3fef7d0e287_dGVzdHMvdGVzdC1zdGF0dXMudA==..8ee3889bab927284e2ebb5ad75eb943f40e2fd5f_dGVzdHMvdGVzdC1zdGF0dXMudA== 100644 --- a/tests/test-status.t +++ b/tests/test-status.t @@ -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