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 } |
|