##// END OF EJS Templates
dirstate-v2: Drop parent directory cache when removing a dirstate node...
Simon Sapin -
r48141:9d58e54b default
parent child Browse files
Show More
@@ -712,11 +712,17 b" impl<'on_disk> super::dispatch::Dirstate"
712 had_entry: bool,
712 had_entry: bool,
713 had_copy_source: bool,
713 had_copy_source: bool,
714 }
714 }
715
716 /// If this returns `Ok(Some((dropped, removed)))`, then
717 ///
718 /// * `dropped` is about the leaf node that was at `filename`
719 /// * `removed` is whether this particular level of recursion just
720 /// removed a node in `nodes`.
715 fn recur<'on_disk>(
721 fn recur<'on_disk>(
716 on_disk: &'on_disk [u8],
722 on_disk: &'on_disk [u8],
717 nodes: &mut ChildNodes<'on_disk>,
723 nodes: &mut ChildNodes<'on_disk>,
718 path: &HgPath,
724 path: &HgPath,
719 ) -> Result<Option<Dropped>, DirstateV2ParseError> {
725 ) -> Result<Option<(Dropped, bool)>, DirstateV2ParseError> {
720 let (first_path_component, rest_of_path) =
726 let (first_path_component, rest_of_path) =
721 path.split_first_component();
727 path.split_first_component();
722 let node = if let Some(node) =
728 let node = if let Some(node) =
@@ -728,11 +734,21 b" impl<'on_disk> super::dispatch::Dirstate"
728 };
734 };
729 let dropped;
735 let dropped;
730 if let Some(rest) = rest_of_path {
736 if let Some(rest) = rest_of_path {
731 if let Some(d) = recur(on_disk, &mut node.children, rest)? {
737 if let Some((d, removed)) =
738 recur(on_disk, &mut node.children, rest)?
739 {
732 dropped = d;
740 dropped = d;
733 if dropped.was_tracked {
741 if dropped.was_tracked {
734 node.tracked_descendants_count -= 1;
742 node.tracked_descendants_count -= 1;
735 }
743 }
744
745 // Directory caches must be invalidated when removing a
746 // child node
747 if removed {
748 if let NodeData::CachedDirectory { .. } = &node.data {
749 node.data = NodeData::None
750 }
751 }
736 } else {
752 } else {
737 return Ok(None);
753 return Ok(None);
738 }
754 }
@@ -752,16 +768,18 b" impl<'on_disk> super::dispatch::Dirstate"
752 }
768 }
753 // After recursion, for both leaf (rest_of_path is None) nodes and
769 // After recursion, for both leaf (rest_of_path is None) nodes and
754 // parent nodes, remove a node if it just became empty.
770 // parent nodes, remove a node if it just became empty.
755 if !node.data.has_entry()
771 let remove = !node.data.has_entry()
756 && node.copy_source.is_none()
772 && node.copy_source.is_none()
757 && node.children.is_empty()
773 && node.children.is_empty();
758 {
774 if remove {
759 nodes.make_mut(on_disk)?.remove(first_path_component);
775 nodes.make_mut(on_disk)?.remove(first_path_component);
760 }
776 }
761 Ok(Some(dropped))
777 Ok(Some((dropped, remove)))
762 }
778 }
763
779
764 if let Some(dropped) = recur(self.on_disk, &mut self.root, filename)? {
780 if let Some((dropped, _removed)) =
781 recur(self.on_disk, &mut self.root, filename)?
782 {
765 if dropped.had_entry {
783 if dropped.had_entry {
766 self.nodes_with_entry_count -= 1
784 self.nodes_with_entry_count -= 1
767 }
785 }
@@ -957,4 +957,18 b' Creating a new file changes the directory\xe2\x80\x99s mtime, invalidating the cache'
957 $ hg status
957 $ hg status
958 ? subdir/unknown
958 ? subdir/unknown
959
959
960 $ rm subdir/unknown
961 $ hg status
962
963 Removing a node from the dirstate resets the cache for its parent directory
964
965 $ hg forget subdir/a
966 $ hg debugdirstate --dirs --no-dates | grep '^d'
967 d 0 0 set subdir
968 $ hg ci -qm '#1'
969 $ hg debugdirstate --dirs --no-dates | grep '^d'
970 d 0 0 unset subdir
971 $ hg status
972 ? subdir/a
973
960 #endif
974 #endif
General Comments 0
You need to be logged in to leave comments. Login now