rust/hg-core/src/dirstate_tree/status.rs
branchstable
changeset 49366 288de6f5d724
parent 49142 c4ccd0346f5c
parent 49337 6cd249556e20
child 49421 7e5377bdb66e
equal deleted inserted replaced
49364:e8ea403b1c46 49366:288de6f5d724
     3 use crate::dirstate::status::StatusPath;
     3 use crate::dirstate::status::StatusPath;
     4 use crate::dirstate_tree::dirstate_map::BorrowedPath;
     4 use crate::dirstate_tree::dirstate_map::BorrowedPath;
     5 use crate::dirstate_tree::dirstate_map::ChildNodesRef;
     5 use crate::dirstate_tree::dirstate_map::ChildNodesRef;
     6 use crate::dirstate_tree::dirstate_map::DirstateMap;
     6 use crate::dirstate_tree::dirstate_map::DirstateMap;
     7 use crate::dirstate_tree::dirstate_map::DirstateVersion;
     7 use crate::dirstate_tree::dirstate_map::DirstateVersion;
     8 use crate::dirstate_tree::dirstate_map::NodeData;
       
     9 use crate::dirstate_tree::dirstate_map::NodeRef;
     8 use crate::dirstate_tree::dirstate_map::NodeRef;
    10 use crate::dirstate_tree::on_disk::DirstateV2ParseError;
     9 use crate::dirstate_tree::on_disk::DirstateV2ParseError;
    11 use crate::matchers::get_ignore_function;
    10 use crate::matchers::get_ignore_function;
    12 use crate::matchers::Matcher;
    11 use crate::matchers::Matcher;
    13 use crate::utils::files::get_bytes_from_os_string;
    12 use crate::utils::files::get_bytes_from_os_string;
    14 use crate::utils::files::get_path_from_bytes;
    13 use crate::utils::files::get_path_from_bytes;
    15 use crate::utils::hg_path::HgPath;
    14 use crate::utils::hg_path::HgPath;
    16 use crate::BadMatch;
    15 use crate::BadMatch;
    17 use crate::DirstateStatus;
    16 use crate::DirstateStatus;
    18 use crate::EntryState;
       
    19 use crate::HgPathBuf;
    17 use crate::HgPathBuf;
    20 use crate::HgPathCow;
    18 use crate::HgPathCow;
    21 use crate::PatternFileWarning;
    19 use crate::PatternFileWarning;
    22 use crate::StatusError;
    20 use crate::StatusError;
    23 use crate::StatusOptions;
    21 use crate::StatusOptions;
   153             && dmap.dirstate_version == DirstateVersion::V2);
   151             && dmap.dirstate_version == DirstateVersion::V2);
   154 
   152 
   155     // Remove outdated mtimes before adding new mtimes, in case a given
   153     // Remove outdated mtimes before adding new mtimes, in case a given
   156     // directory is both
   154     // directory is both
   157     for path in &outdated {
   155     for path in &outdated {
   158         let node = dmap.get_or_insert(path)?;
   156         dmap.clear_cached_mtime(path)?;
   159         if let NodeData::CachedDirectory { .. } = &node.data {
       
   160             node.data = NodeData::None
       
   161         }
       
   162     }
   157     }
   163     for (path, mtime) in &new_cachable {
   158     for (path, mtime) in &new_cachable {
   164         let node = dmap.get_or_insert(path)?;
   159         dmap.set_cached_mtime(path, *mtime)?;
   165         match &node.data {
       
   166             NodeData::Entry(_) => {} // Don’t overwrite an entry
       
   167             NodeData::CachedDirectory { .. } | NodeData::None => {
       
   168                 node.data = NodeData::CachedDirectory { mtime: *mtime }
       
   169             }
       
   170         }
       
   171     }
   160     }
   172 
   161 
   173     Ok((outcome, warnings))
   162     Ok((outcome, warnings))
   174 }
   163 }
   175 
   164 
   482                 fs_metadata,
   471                 fs_metadata,
   483                 dirstate_node,
   472                 dirstate_node,
   484             )?
   473             )?
   485         } else {
   474         } else {
   486             if file_or_symlink && self.matcher.matches(hg_path) {
   475             if file_or_symlink && self.matcher.matches(hg_path) {
   487                 if let Some(state) = dirstate_node.state()? {
   476                 if let Some(entry) = dirstate_node.entry()? {
   488                     match state {
   477                     if !entry.any_tracked() {
   489                         EntryState::Added => {
   478                         // Forward-compat if we start tracking unknown/ignored
   490                             self.push_outcome(Outcome::Added, &dirstate_node)?
   479                         // files for caching reasons
   491                         }
   480                         self.mark_unknown_or_ignored(
   492                         EntryState::Removed => self
   481                             has_ignored_ancestor,
   493                             .push_outcome(Outcome::Removed, &dirstate_node)?,
   482                             hg_path,
   494                         EntryState::Merged => self
   483                         );
   495                             .push_outcome(Outcome::Modified, &dirstate_node)?,
   484                     }
   496                         EntryState::Normal => self
   485                     if entry.added() {
   497                             .handle_normal_file(&dirstate_node, fs_metadata)?,
   486                         self.push_outcome(Outcome::Added, &dirstate_node)?;
       
   487                     } else if entry.removed() {
       
   488                         self.push_outcome(Outcome::Removed, &dirstate_node)?;
       
   489                     } else if entry.modified() {
       
   490                         self.push_outcome(Outcome::Modified, &dirstate_node)?;
       
   491                     } else {
       
   492                         self.handle_normal_file(&dirstate_node, fs_metadata)?;
   498                     }
   493                     }
   499                 } else {
   494                 } else {
   500                     // `node.entry.is_none()` indicates a "directory"
   495                     // `node.entry.is_none()` indicates a "directory"
   501                     // node, but the filesystem has a file
   496                     // node, but the filesystem has a file
   502                     self.mark_unknown_or_ignored(
   497                     self.mark_unknown_or_ignored(
   602                 .push((hg_path, directory_mtime))
   597                 .push((hg_path, directory_mtime))
   603         }
   598         }
   604         Ok(())
   599         Ok(())
   605     }
   600     }
   606 
   601 
   607     /// A file with `EntryState::Normal` in the dirstate was found in the
   602     /// A file that is clean in the dirstate was found in the filesystem
   608     /// filesystem
       
   609     fn handle_normal_file(
   603     fn handle_normal_file(
   610         &self,
   604         &self,
   611         dirstate_node: &NodeRef<'tree, 'on_disk>,
   605         dirstate_node: &NodeRef<'tree, 'on_disk>,
   612         fs_metadata: &std::fs::Metadata,
   606         fs_metadata: &std::fs::Metadata,
   613     ) -> Result<(), DirstateV2ParseError> {
   607     ) -> Result<(), DirstateV2ParseError> {
   676     /// Does nothing on a "directory" node
   670     /// Does nothing on a "directory" node
   677     fn mark_removed_or_deleted_if_file(
   671     fn mark_removed_or_deleted_if_file(
   678         &self,
   672         &self,
   679         dirstate_node: &NodeRef<'tree, 'on_disk>,
   673         dirstate_node: &NodeRef<'tree, 'on_disk>,
   680     ) -> Result<(), DirstateV2ParseError> {
   674     ) -> Result<(), DirstateV2ParseError> {
   681         if let Some(state) = dirstate_node.state()? {
   675         if let Some(entry) = dirstate_node.entry()? {
       
   676             if !entry.any_tracked() {
       
   677                 // Future-compat for when we start storing ignored and unknown
       
   678                 // files for caching reasons
       
   679                 return Ok(());
       
   680             }
   682             let path = dirstate_node.full_path(self.dmap.on_disk)?;
   681             let path = dirstate_node.full_path(self.dmap.on_disk)?;
   683             if self.matcher.matches(path) {
   682             if self.matcher.matches(path) {
   684                 if let EntryState::Removed = state {
   683                 if entry.removed() {
   685                     self.push_outcome(Outcome::Removed, dirstate_node)?
   684                     self.push_outcome(Outcome::Removed, dirstate_node)?
   686                 } else {
   685                 } else {
   687                     self.push_outcome(Outcome::Deleted, &dirstate_node)?
   686                     self.push_outcome(Outcome::Deleted, &dirstate_node)?
   688                 }
   687                 }
   689             }
   688             }