rust/hg-core/src/operations/dirstate_status.rs
changeset 48083 bf8837e3d7ce
parent 48082 d3eb5f50052c
child 48084 3d0a9c6e614d
equal deleted inserted replaced
48082:d3eb5f50052c 48083:bf8837e3d7ce
     1 // dirstate_status.rs
       
     2 //
       
     3 // Copyright 2019, Raphaël Gomès <rgomes@octobus.net>
       
     4 //
       
     5 // This software may be used and distributed according to the terms of the
       
     6 // GNU General Public License version 2 or any later version.
       
     7 
       
     8 use crate::dirstate::status::{build_response, Dispatch, Status};
       
     9 use crate::matchers::Matcher;
       
    10 use crate::{DirstateStatus, StatusError};
       
    11 
       
    12 impl<'a, M: ?Sized + Matcher + Sync> Status<'a, M> {
       
    13     pub(crate) fn run(&self) -> Result<DirstateStatus<'a>, StatusError> {
       
    14         let (traversed_sender, traversed_receiver) =
       
    15             crossbeam_channel::unbounded();
       
    16 
       
    17         // Step 1: check the files explicitly mentioned by the user
       
    18         let (work, mut results) = self.walk_explicit(traversed_sender.clone());
       
    19 
       
    20         if !work.is_empty() {
       
    21             // Hashmaps are quite a bit slower to build than vecs, so only
       
    22             // build it if needed.
       
    23             let old_results = results.iter().cloned().collect();
       
    24 
       
    25             // Step 2: recursively check the working directory for changes if
       
    26             // needed
       
    27             for (dir, dispatch) in work {
       
    28                 match dispatch {
       
    29                     Dispatch::Directory { was_file } => {
       
    30                         if was_file {
       
    31                             results.push((dir.to_owned(), Dispatch::Removed));
       
    32                         }
       
    33                         if self.options.list_ignored
       
    34                             || self.options.list_unknown
       
    35                                 && !self.dir_ignore(&dir)
       
    36                         {
       
    37                             self.traverse(
       
    38                                 &dir,
       
    39                                 &old_results,
       
    40                                 &mut results,
       
    41                                 traversed_sender.clone(),
       
    42                             );
       
    43                         }
       
    44                     }
       
    45                     _ => {
       
    46                         unreachable!("There can only be directories in `work`")
       
    47                     }
       
    48                 }
       
    49             }
       
    50         }
       
    51 
       
    52         if !self.matcher.is_exact() {
       
    53             if self.options.list_unknown {
       
    54                 self.handle_unknowns(&mut results);
       
    55             } else {
       
    56                 // TODO this is incorrect, see issue6335
       
    57                 // This requires a fix in both Python and Rust that can happen
       
    58                 // with other pending changes to `status`.
       
    59                 self.extend_from_dmap(&mut results);
       
    60             }
       
    61         }
       
    62 
       
    63         drop(traversed_sender);
       
    64         let traversed = traversed_receiver
       
    65             .into_iter()
       
    66             .map(std::borrow::Cow::Owned)
       
    67             .collect();
       
    68 
       
    69         Ok(build_response(results, traversed))
       
    70     }
       
    71 }