Mercurial > hg
comparison 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 |
comparison
equal
deleted
inserted
replaced
49554:ecf9788cd9c4 | 49555:8ee3889bab92 |
---|---|
301 } | 301 } |
302 | 302 |
303 fn check_for_outdated_directory_cache( | 303 fn check_for_outdated_directory_cache( |
304 &self, | 304 &self, |
305 dirstate_node: &NodeRef<'tree, 'on_disk>, | 305 dirstate_node: &NodeRef<'tree, 'on_disk>, |
306 ) -> Result<(), DirstateV2ParseError> { | 306 ) -> Result<bool, DirstateV2ParseError> { |
307 if self.ignore_patterns_have_changed == Some(true) | 307 if self.ignore_patterns_have_changed == Some(true) |
308 && dirstate_node.cached_directory_mtime()?.is_some() | 308 && dirstate_node.cached_directory_mtime()?.is_some() |
309 { | 309 { |
310 self.outdated_cached_directories.lock().unwrap().push( | 310 self.outdated_cached_directories.lock().unwrap().push( |
311 dirstate_node | 311 dirstate_node |
312 .full_path_borrowed(self.dmap.on_disk)? | 312 .full_path_borrowed(self.dmap.on_disk)? |
313 .detach_from_tree(), | 313 .detach_from_tree(), |
314 ) | 314 ); |
315 } | 315 return Ok(true); |
316 Ok(()) | 316 } |
317 Ok(false) | |
317 } | 318 } |
318 | 319 |
319 /// If this returns true, we can get accurate results by only using | 320 /// If this returns true, we can get accurate results by only using |
320 /// `symlink_metadata` for child nodes that exist in the dirstate and don’t | 321 /// `symlink_metadata` for child nodes that exist in the dirstate and don’t |
321 /// need to call `read_dir`. | 322 /// need to call `read_dir`. |
471 fs_path: &Path, | 472 fs_path: &Path, |
472 fs_metadata: &std::fs::Metadata, | 473 fs_metadata: &std::fs::Metadata, |
473 dirstate_node: NodeRef<'tree, 'on_disk>, | 474 dirstate_node: NodeRef<'tree, 'on_disk>, |
474 has_ignored_ancestor: &'ancestor HasIgnoredAncestor<'ancestor>, | 475 has_ignored_ancestor: &'ancestor HasIgnoredAncestor<'ancestor>, |
475 ) -> Result<(), DirstateV2ParseError> { | 476 ) -> Result<(), DirstateV2ParseError> { |
476 self.check_for_outdated_directory_cache(&dirstate_node)?; | 477 let outdated_dircache = |
478 self.check_for_outdated_directory_cache(&dirstate_node)?; | |
477 let hg_path = &dirstate_node.full_path_borrowed(self.dmap.on_disk)?; | 479 let hg_path = &dirstate_node.full_path_borrowed(self.dmap.on_disk)?; |
478 let file_type = fs_metadata.file_type(); | 480 let file_type = fs_metadata.file_type(); |
479 let file_or_symlink = file_type.is_file() || file_type.is_symlink(); | 481 let file_or_symlink = file_type.is_file() || file_type.is_symlink(); |
480 if !file_or_symlink { | 482 if !file_or_symlink { |
481 // If we previously had a file here, it was removed (with | 483 // If we previously had a file here, it was removed (with |
508 )?; | 510 )?; |
509 self.maybe_save_directory_mtime( | 511 self.maybe_save_directory_mtime( |
510 children_all_have_dirstate_node_or_are_ignored, | 512 children_all_have_dirstate_node_or_are_ignored, |
511 fs_metadata, | 513 fs_metadata, |
512 dirstate_node, | 514 dirstate_node, |
515 outdated_dircache, | |
513 )? | 516 )? |
514 } else { | 517 } else { |
515 if file_or_symlink && self.matcher.matches(&hg_path) { | 518 if file_or_symlink && self.matcher.matches(&hg_path) { |
516 if let Some(entry) = dirstate_node.entry()? { | 519 if let Some(entry) = dirstate_node.entry()? { |
517 if !entry.any_tracked() { | 520 if !entry.any_tracked() { |
547 } | 550 } |
548 } | 551 } |
549 Ok(()) | 552 Ok(()) |
550 } | 553 } |
551 | 554 |
555 /// Save directory mtime if applicable. | |
556 /// | |
557 /// `outdated_directory_cache` is `true` if we've just invalidated the | |
558 /// cache for this directory in `check_for_outdated_directory_cache`, | |
559 /// which forces the update. | |
552 fn maybe_save_directory_mtime( | 560 fn maybe_save_directory_mtime( |
553 &self, | 561 &self, |
554 children_all_have_dirstate_node_or_are_ignored: bool, | 562 children_all_have_dirstate_node_or_are_ignored: bool, |
555 directory_metadata: &std::fs::Metadata, | 563 directory_metadata: &std::fs::Metadata, |
556 dirstate_node: NodeRef<'tree, 'on_disk>, | 564 dirstate_node: NodeRef<'tree, 'on_disk>, |
565 outdated_directory_cache: bool, | |
557 ) -> Result<(), DirstateV2ParseError> { | 566 ) -> Result<(), DirstateV2ParseError> { |
558 if !children_all_have_dirstate_node_or_are_ignored { | 567 if !children_all_have_dirstate_node_or_are_ignored { |
559 return Ok(()); | 568 return Ok(()); |
560 } | 569 } |
561 // All filesystem directory entries from `read_dir` have a | 570 // All filesystem directory entries from `read_dir` have a |
619 // the wrong tick. | 628 // the wrong tick. |
620 // | 629 // |
621 // We deem this scenario (unlike the previous one) to be | 630 // We deem this scenario (unlike the previous one) to be |
622 // unlikely enough in practice. | 631 // unlikely enough in practice. |
623 | 632 |
624 let is_up_to_date = | 633 let is_up_to_date = if let Some(cached) = |
625 if let Some(cached) = dirstate_node.cached_directory_mtime()? { | 634 dirstate_node.cached_directory_mtime()? |
626 cached.likely_equal(directory_mtime) | 635 { |
627 } else { | 636 !outdated_directory_cache && cached.likely_equal(directory_mtime) |
628 false | 637 } else { |
629 }; | 638 false |
639 }; | |
630 if !is_up_to_date { | 640 if !is_up_to_date { |
631 let hg_path = dirstate_node | 641 let hg_path = dirstate_node |
632 .full_path_borrowed(self.dmap.on_disk)? | 642 .full_path_borrowed(self.dmap.on_disk)? |
633 .detach_from_tree(); | 643 .detach_from_tree(); |
634 self.new_cacheable_directories | 644 self.new_cacheable_directories |