annotate rust/hg-core/src/dirstate/status.rs @ 44925:ce8fe77102f4

rust: fix false comment about mpsc::Sender We need Sync to share the Sender reference across threads.
author Yuya Nishihara <yuya@tcha.org>
date Mon, 25 May 2020 23:02:07 +0900
parents 73d6ce2746d2
children 14125dec0e39
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
43271
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
1 // status.rs
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
2 //
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
3 // Copyright 2019 Raphaël Gomès <rgomes@octobus.net>
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
4 //
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
5 // This software may be used and distributed according to the terms of the
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
6 // GNU General Public License version 2 or any later version.
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
7
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
8 //! Rust implementation of dirstate.status (dirstate.py).
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
9 //! It is currently missing a lot of functionality compared to the Python one
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
10 //! and will only be triggered in narrow cases.
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
11
43605
8210c3f46912 rust: introduce SIZE_FROM_OTHER_PARENT constant
Raphaël Gomès <rgomes@octobus.net>
parents: 43604
diff changeset
12 use crate::{
8210c3f46912 rust: introduce SIZE_FROM_OTHER_PARENT constant
Raphaël Gomès <rgomes@octobus.net>
parents: 43604
diff changeset
13 dirstate::SIZE_FROM_OTHER_PARENT,
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
14 filepatterns::PatternFileWarning,
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
15 matchers::{get_ignore_function, Matcher, VisitChildrenSet},
43605
8210c3f46912 rust: introduce SIZE_FROM_OTHER_PARENT constant
Raphaël Gomès <rgomes@octobus.net>
parents: 43604
diff changeset
16 utils::{
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
17 files::{find_dirs, HgMetadata},
44523
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
18 hg_path::{
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
19 hg_path_to_path_buf, os_string_to_hg_path_buf, HgPath, HgPathBuf,
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
20 HgPathError,
44523
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
21 },
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
22 path_auditor::PathAuditor,
43605
8210c3f46912 rust: introduce SIZE_FROM_OTHER_PARENT constant
Raphaël Gomès <rgomes@octobus.net>
parents: 43604
diff changeset
23 },
44527
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
24 CopyMap, DirstateEntry, DirstateMap, EntryState, FastHashMap,
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
25 PatternError,
43605
8210c3f46912 rust: introduce SIZE_FROM_OTHER_PARENT constant
Raphaël Gomès <rgomes@octobus.net>
parents: 43604
diff changeset
26 };
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
27 use lazy_static::lazy_static;
44541
d880805d5442 hg-core: add function timing information
Raphaël Gomès <rgomes@octobus.net>
parents: 44539
diff changeset
28 use micro_timer::timed;
43271
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
29 use rayon::prelude::*;
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
30 use std::{
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
31 borrow::Cow,
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
32 collections::HashSet,
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
33 fs::{read_dir, DirEntry},
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
34 io::ErrorKind,
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
35 ops::Deref,
44597
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
36 path::{Path, PathBuf},
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
37 };
43271
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
38
44526
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
39 /// Wrong type of file from a `BadMatch`
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
40 /// Note: a lot of those don't exist on all platforms.
44536
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
41 #[derive(Debug, Copy, Clone)]
44526
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
42 pub enum BadType {
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
43 CharacterDevice,
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
44 BlockDevice,
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
45 FIFO,
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
46 Socket,
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
47 Directory,
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
48 Unknown,
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
49 }
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
50
44529
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Raphaël Gomès <rgomes@octobus.net>
parents: 44528
diff changeset
51 impl ToString for BadType {
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Raphaël Gomès <rgomes@octobus.net>
parents: 44528
diff changeset
52 fn to_string(&self) -> String {
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Raphaël Gomès <rgomes@octobus.net>
parents: 44528
diff changeset
53 match self {
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Raphaël Gomès <rgomes@octobus.net>
parents: 44528
diff changeset
54 BadType::CharacterDevice => "character device",
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Raphaël Gomès <rgomes@octobus.net>
parents: 44528
diff changeset
55 BadType::BlockDevice => "block device",
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Raphaël Gomès <rgomes@octobus.net>
parents: 44528
diff changeset
56 BadType::FIFO => "fifo",
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Raphaël Gomès <rgomes@octobus.net>
parents: 44528
diff changeset
57 BadType::Socket => "socket",
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Raphaël Gomès <rgomes@octobus.net>
parents: 44528
diff changeset
58 BadType::Directory => "directory",
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Raphaël Gomès <rgomes@octobus.net>
parents: 44528
diff changeset
59 BadType::Unknown => "unknown",
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Raphaël Gomès <rgomes@octobus.net>
parents: 44528
diff changeset
60 }
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Raphaël Gomès <rgomes@octobus.net>
parents: 44528
diff changeset
61 .to_string()
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Raphaël Gomès <rgomes@octobus.net>
parents: 44528
diff changeset
62 }
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Raphaël Gomès <rgomes@octobus.net>
parents: 44528
diff changeset
63 }
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Raphaël Gomès <rgomes@octobus.net>
parents: 44528
diff changeset
64
44526
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
65 /// Was explicitly matched but cannot be found/accessed
44536
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
66 #[derive(Debug, Copy, Clone)]
44526
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
67 pub enum BadMatch {
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
68 OsError(i32),
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
69 BadType(BadType),
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
70 }
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
71
43602
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
72 /// Marker enum used to dispatch new status entries into the right collections.
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
73 /// Is similar to `crate::EntryState`, but represents the transient state of
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
74 /// entries during the lifetime of a command.
44536
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
75 #[derive(Debug, Copy, Clone)]
43602
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
76 enum Dispatch {
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
77 Unsure,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
78 Modified,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
79 Added,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
80 Removed,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
81 Deleted,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
82 Clean,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
83 Unknown,
44526
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
84 Ignored,
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
85 /// Empty dispatch, the file is not worth listing
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
86 None,
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
87 /// Was explicitly matched but cannot be found/accessed
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
88 Bad(BadMatch),
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
89 Directory {
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
90 /// True if the directory used to be a file in the dmap so we can say
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
91 /// that it's been removed.
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
92 was_file: bool,
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
93 },
43602
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
94 }
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
95
43915
8c77826116f7 rust-dirstate-status: add `walk_explicit` implementation, use `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43818
diff changeset
96 type IoResult<T> = std::io::Result<T>;
44597
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
97 /// `Box<dyn Trait>` is syntactic sugar for `Box<dyn Trait, 'static>`, so add
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
98 /// an explicit lifetime here to not fight `'static` bounds "out of nowhere".
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
99 type IgnoreFnType<'a> = Box<dyn for<'r> Fn(&'r HgPath) -> bool + Sync + 'a>;
43915
8c77826116f7 rust-dirstate-status: add `walk_explicit` implementation, use `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43818
diff changeset
100
43604
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
101 /// Dates and times that are outside the 31-bit signed range are compared
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
102 /// modulo 2^31. This should prevent hg from behaving badly with very large
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
103 /// files or corrupt dates while still having a high probability of detecting
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
104 /// changes. (issue2608)
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
105 /// TODO I haven't found a way of having `b` be `Into<i32>`, since `From<u64>`
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
106 /// is not defined for `i32`, and there is no `As` trait. This forces the
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
107 /// caller to cast `b` as `i32`.
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
108 fn mod_compare(a: i32, b: i32) -> bool {
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
109 a & i32::max_value() != b & i32::max_value()
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
110 }
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
111
44523
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
112 /// Return a sorted list containing information about the entries
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
113 /// in the directory.
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
114 ///
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
115 /// * `skip_dot_hg` - Return an empty vec if `path` contains a `.hg` directory
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
116 fn list_directory(
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
117 path: impl AsRef<Path>,
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
118 skip_dot_hg: bool,
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
119 ) -> std::io::Result<Vec<(HgPathBuf, DirEntry)>> {
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
120 let mut results = vec![];
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
121 let entries = read_dir(path.as_ref())?;
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
122
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
123 for entry in entries {
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
124 let entry = entry?;
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
125 let filename = os_string_to_hg_path_buf(entry.file_name())?;
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
126 let file_type = entry.file_type()?;
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
127 if skip_dot_hg && filename.as_bytes() == b".hg" && file_type.is_dir() {
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
128 return Ok(vec![]);
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
129 } else {
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
130 results.push((HgPathBuf::from(filename), entry))
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
131 }
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
132 }
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
133
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
134 results.sort_unstable_by_key(|e| e.0.clone());
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
135 Ok(results)
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
136 }
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
137
43602
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
138 /// The file corresponding to the dirstate entry was found on the filesystem.
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
139 fn dispatch_found(
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
140 filename: impl AsRef<HgPath>,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
141 entry: DirstateEntry,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
142 metadata: HgMetadata,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
143 copy_map: &CopyMap,
44524
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
144 options: StatusOptions,
43602
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
145 ) -> Dispatch {
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
146 let DirstateEntry {
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
147 state,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
148 mode,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
149 mtime,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
150 size,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
151 } = entry;
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
152
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
153 let HgMetadata {
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
154 st_mode,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
155 st_size,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
156 st_mtime,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
157 ..
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
158 } = metadata;
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
159
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
160 match state {
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
161 EntryState::Normal => {
43604
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
162 let size_changed = mod_compare(size, st_size as i32);
43602
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
163 let mode_changed =
44524
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
164 (mode ^ st_mode as i32) & 0o100 != 0o000 && options.check_exec;
43604
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
165 let metadata_changed = size >= 0 && (size_changed || mode_changed);
43605
8210c3f46912 rust: introduce SIZE_FROM_OTHER_PARENT constant
Raphaël Gomès <rgomes@octobus.net>
parents: 43604
diff changeset
166 let other_parent = size == SIZE_FROM_OTHER_PARENT;
43604
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
167 if metadata_changed
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
168 || other_parent
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
169 || copy_map.contains_key(filename.as_ref())
43602
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
170 {
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
171 Dispatch::Modified
43604
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
172 } else if mod_compare(mtime, st_mtime as i32) {
43602
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
173 Dispatch::Unsure
44524
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
174 } else if st_mtime == options.last_normal_time {
43602
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
175 // the file may have just been marked as normal and
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
176 // it may have changed in the same second without
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
177 // changing its size. This can happen if we quickly
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
178 // do multiple commits. Force lookup, so we don't
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
179 // miss such a racy file change.
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
180 Dispatch::Unsure
44524
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
181 } else if options.list_clean {
43602
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
182 Dispatch::Clean
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
183 } else {
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
184 Dispatch::None
43602
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
185 }
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
186 }
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
187 EntryState::Merged => Dispatch::Modified,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
188 EntryState::Added => Dispatch::Added,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
189 EntryState::Removed => Dispatch::Removed,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
190 EntryState::Unknown => Dispatch::Unknown,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
191 }
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
192 }
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
193
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
194 /// The file corresponding to this Dirstate entry is missing.
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
195 fn dispatch_missing(state: EntryState) -> Dispatch {
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
196 match state {
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
197 // File was removed from the filesystem during commands
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
198 EntryState::Normal | EntryState::Merged | EntryState::Added => {
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
199 Dispatch::Deleted
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
200 }
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
201 // File was removed, everything is normal
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
202 EntryState::Removed => Dispatch::Removed,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
203 // File is unknown to Mercurial, everything is normal
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
204 EntryState::Unknown => Dispatch::Unknown,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
205 }
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
206 }
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
207
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
208 lazy_static! {
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
209 static ref DEFAULT_WORK: HashSet<&'static HgPath> = {
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
210 let mut h = HashSet::new();
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
211 h.insert(HgPath::new(b""));
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
212 h
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
213 };
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
214 }
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
215
43915
8c77826116f7 rust-dirstate-status: add `walk_explicit` implementation, use `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43818
diff changeset
216 /// Get stat data about the files explicitly specified by match.
8c77826116f7 rust-dirstate-status: add `walk_explicit` implementation, use `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43818
diff changeset
217 /// TODO subrepos
44541
d880805d5442 hg-core: add function timing information
Raphaël Gomès <rgomes@octobus.net>
parents: 44539
diff changeset
218 #[timed]
43915
8c77826116f7 rust-dirstate-status: add `walk_explicit` implementation, use `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43818
diff changeset
219 fn walk_explicit<'a>(
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
220 files: Option<&'a HashSet<&HgPath>>,
43915
8c77826116f7 rust-dirstate-status: add `walk_explicit` implementation, use `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43818
diff changeset
221 dmap: &'a DirstateMap,
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
222 root_dir: impl AsRef<Path> + Sync + Send + 'a,
44524
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
223 options: StatusOptions,
44838
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
224 traversed_sender: crossbeam::Sender<HgPathBuf>,
43915
8c77826116f7 rust-dirstate-status: add `walk_explicit` implementation, use `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43818
diff changeset
225 ) -> impl ParallelIterator<Item = IoResult<(&'a HgPath, Dispatch)>> {
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
226 files
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
227 .unwrap_or(&DEFAULT_WORK)
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
228 .par_iter()
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
229 .map(move |filename| {
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
230 // TODO normalization
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
231 let normalized = filename.as_ref();
43915
8c77826116f7 rust-dirstate-status: add `walk_explicit` implementation, use `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43818
diff changeset
232
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
233 let buf = match hg_path_to_path_buf(normalized) {
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
234 Ok(x) => x,
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
235 Err(e) => return Some(Err(e.into())),
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
236 };
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
237 let target = root_dir.as_ref().join(buf);
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
238 let st = target.symlink_metadata();
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
239 let in_dmap = dmap.get(normalized);
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
240 match st {
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
241 Ok(meta) => {
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
242 let file_type = meta.file_type();
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
243 return if file_type.is_file() || file_type.is_symlink() {
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
244 if let Some(entry) = in_dmap {
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
245 return Some(Ok((
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
246 normalized,
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
247 dispatch_found(
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
248 &normalized,
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
249 *entry,
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
250 HgMetadata::from_metadata(meta),
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
251 &dmap.copy_map,
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
252 options,
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
253 ),
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
254 )));
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
255 }
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
256 Some(Ok((normalized, Dispatch::Unknown)))
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
257 } else {
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
258 if file_type.is_dir() {
44838
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
259 if options.collect_traversed_dirs {
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
260 // The receiver always outlives the sender,
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
261 // so unwrap.
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
262 traversed_sender
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
263 .send(normalized.to_owned())
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
264 .unwrap()
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
265 }
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
266 Some(Ok((
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
267 normalized,
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
268 Dispatch::Directory {
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
269 was_file: in_dmap.is_some(),
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
270 },
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
271 )))
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
272 } else {
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
273 Some(Ok((
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
274 normalized,
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
275 Dispatch::Bad(BadMatch::BadType(
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
276 // TODO do more than unknown
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
277 // Support for all `BadType` variant
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
278 // varies greatly between platforms.
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
279 // So far, no tests check the type and
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
280 // this should be good enough for most
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
281 // users.
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
282 BadType::Unknown,
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
283 )),
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
284 )))
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
285 }
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
286 };
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
287 }
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
288 Err(_) => {
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
289 if let Some(entry) = in_dmap {
43915
8c77826116f7 rust-dirstate-status: add `walk_explicit` implementation, use `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43818
diff changeset
290 return Some(Ok((
8c77826116f7 rust-dirstate-status: add `walk_explicit` implementation, use `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43818
diff changeset
291 normalized,
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
292 dispatch_missing(entry.state),
43915
8c77826116f7 rust-dirstate-status: add `walk_explicit` implementation, use `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43818
diff changeset
293 )));
8c77826116f7 rust-dirstate-status: add `walk_explicit` implementation, use `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43818
diff changeset
294 }
8c77826116f7 rust-dirstate-status: add `walk_explicit` implementation, use `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43818
diff changeset
295 }
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
296 };
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
297 None
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
298 })
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
299 .flatten()
43915
8c77826116f7 rust-dirstate-status: add `walk_explicit` implementation, use `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43818
diff changeset
300 }
8c77826116f7 rust-dirstate-status: add `walk_explicit` implementation, use `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43818
diff changeset
301
44524
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
302 #[derive(Debug, Copy, Clone)]
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
303 pub struct StatusOptions {
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
304 /// Remember the most recent modification timeslot for status, to make
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
305 /// sure we won't miss future size-preserving file content modifications
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
306 /// that happen within the same timeslot.
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
307 pub last_normal_time: i64,
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
308 /// Whether we are on a filesystem with UNIX-like exec flags
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
309 pub check_exec: bool,
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
310 pub list_clean: bool,
44527
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
311 pub list_unknown: bool,
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
312 pub list_ignored: bool,
44838
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
313 /// Whether to collect traversed dirs for applying a callback later.
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
314 /// Used by `hg purge` for example.
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
315 pub collect_traversed_dirs: bool,
44527
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
316 }
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
317
44536
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
318 /// Dispatch a single entry (file, folder, symlink...) found during `traverse`.
44539
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
319 /// If the entry is a folder that needs to be traversed, it will be handled
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
320 /// in a separate thread.
44536
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
321 fn handle_traversed_entry<'a>(
44539
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
322 scope: &rayon::Scope<'a>,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
323 files_sender: &'a crossbeam::Sender<IoResult<(HgPathBuf, Dispatch)>>,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
324 matcher: &'a (impl Matcher + Sync),
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
325 root_dir: impl AsRef<Path> + Sync + Send + Copy + 'a,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
326 dmap: &'a DirstateMap,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
327 old_results: &'a FastHashMap<Cow<HgPath>, Dispatch>,
44597
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
328 ignore_fn: &'a IgnoreFnType,
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
329 dir_ignore_fn: &'a IgnoreFnType,
44527
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
330 options: StatusOptions,
44539
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
331 filename: HgPathBuf,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
332 dir_entry: DirEntry,
44838
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
333 traversed_sender: crossbeam::Sender<HgPathBuf>,
44539
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
334 ) -> IoResult<()> {
44536
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
335 let file_type = dir_entry.file_type()?;
44539
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
336 let entry_option = dmap.get(&filename);
44527
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
337
44748
a467416c493c rust-status: check for '.hg' regardless of file type (issue6300)
Raphaël Gomès <rgomes@octobus.net>
parents: 44747
diff changeset
338 if filename.as_bytes() == b".hg" {
a467416c493c rust-status: check for '.hg' regardless of file type (issue6300)
Raphaël Gomès <rgomes@octobus.net>
parents: 44747
diff changeset
339 // Could be a directory or a symlink
a467416c493c rust-status: check for '.hg' regardless of file type (issue6300)
Raphaël Gomès <rgomes@octobus.net>
parents: 44747
diff changeset
340 return Ok(());
a467416c493c rust-status: check for '.hg' regardless of file type (issue6300)
Raphaël Gomès <rgomes@octobus.net>
parents: 44747
diff changeset
341 }
a467416c493c rust-status: check for '.hg' regardless of file type (issue6300)
Raphaël Gomès <rgomes@octobus.net>
parents: 44747
diff changeset
342
44527
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
343 if file_type.is_dir() {
44539
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
344 handle_traversed_dir(
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
345 scope,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
346 files_sender,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
347 matcher,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
348 root_dir,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
349 dmap,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
350 old_results,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
351 ignore_fn,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
352 dir_ignore_fn,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
353 options,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
354 entry_option,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
355 filename,
44838
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
356 traversed_sender,
44539
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
357 );
44527
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
358 } else if file_type.is_file() || file_type.is_symlink() {
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
359 if let Some(entry) = entry_option {
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
360 if matcher.matches_everything() || matcher.matches(&filename) {
44536
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
361 let metadata = dir_entry.metadata()?;
44539
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
362 files_sender
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
363 .send(Ok((
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
364 filename.to_owned(),
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
365 dispatch_found(
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
366 &filename,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
367 *entry,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
368 HgMetadata::from_metadata(metadata),
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
369 &dmap.copy_map,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
370 options,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
371 ),
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
372 )))
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
373 .unwrap();
44527
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
374 }
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
375 } else if (matcher.matches_everything() || matcher.matches(&filename))
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
376 && !ignore_fn(&filename)
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
377 {
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
378 if (options.list_ignored || matcher.exact_match(&filename))
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
379 && dir_ignore_fn(&filename)
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
380 {
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
381 if options.list_ignored {
44539
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
382 files_sender
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
383 .send(Ok((filename.to_owned(), Dispatch::Ignored)))
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
384 .unwrap();
44527
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
385 }
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
386 } else {
44837
dc60ba32d43b rust-status: don't dispatch unknown file when traversing if not listing unknowns
Raphaël Gomès <rgomes@octobus.net>
parents: 44748
diff changeset
387 if options.list_unknown {
dc60ba32d43b rust-status: don't dispatch unknown file when traversing if not listing unknowns
Raphaël Gomès <rgomes@octobus.net>
parents: 44748
diff changeset
388 files_sender
dc60ba32d43b rust-status: don't dispatch unknown file when traversing if not listing unknowns
Raphaël Gomès <rgomes@octobus.net>
parents: 44748
diff changeset
389 .send(Ok((filename.to_owned(), Dispatch::Unknown)))
dc60ba32d43b rust-status: don't dispatch unknown file when traversing if not listing unknowns
Raphaël Gomès <rgomes@octobus.net>
parents: 44748
diff changeset
390 .unwrap();
dc60ba32d43b rust-status: don't dispatch unknown file when traversing if not listing unknowns
Raphaël Gomès <rgomes@octobus.net>
parents: 44748
diff changeset
391 }
44527
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
392 }
44536
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
393 } else if ignore_fn(&filename) && options.list_ignored {
44539
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
394 files_sender
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
395 .send(Ok((filename.to_owned(), Dispatch::Ignored)))
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
396 .unwrap();
44527
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
397 }
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
398 } else if let Some(entry) = entry_option {
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
399 // Used to be a file or a folder, now something else.
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
400 if matcher.matches_everything() || matcher.matches(&filename) {
44539
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
401 files_sender
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
402 .send(Ok((filename.to_owned(), dispatch_missing(entry.state))))
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
403 .unwrap();
44527
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
404 }
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
405 }
44539
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
406
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
407 Ok(())
44527
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
408 }
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
409
44539
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
410 /// A directory was found in the filesystem and needs to be traversed
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
411 fn handle_traversed_dir<'a>(
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
412 scope: &rayon::Scope<'a>,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
413 files_sender: &'a crossbeam::Sender<IoResult<(HgPathBuf, Dispatch)>>,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
414 matcher: &'a (impl Matcher + Sync),
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
415 root_dir: impl AsRef<Path> + Sync + Send + Copy + 'a,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
416 dmap: &'a DirstateMap,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
417 old_results: &'a FastHashMap<Cow<HgPath>, Dispatch>,
44597
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
418 ignore_fn: &'a IgnoreFnType,
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
419 dir_ignore_fn: &'a IgnoreFnType,
44539
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
420 options: StatusOptions,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
421 entry_option: Option<&'a DirstateEntry>,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
422 directory: HgPathBuf,
44838
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
423 traversed_sender: crossbeam::Sender<HgPathBuf>,
44539
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
424 ) {
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
425 scope.spawn(move |_| {
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
426 // Nested `if` until `rust-lang/rust#53668` is stable
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
427 if let Some(entry) = entry_option {
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
428 // Used to be a file, is now a folder
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
429 if matcher.matches_everything() || matcher.matches(&directory) {
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
430 files_sender
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
431 .send(Ok((
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
432 directory.to_owned(),
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
433 dispatch_missing(entry.state),
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
434 )))
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
435 .unwrap();
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
436 }
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
437 }
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
438 // Do we need to traverse it?
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
439 if !ignore_fn(&directory) || options.list_ignored {
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
440 traverse_dir(
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
441 files_sender,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
442 matcher,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
443 root_dir,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
444 dmap,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
445 directory,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
446 &old_results,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
447 ignore_fn,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
448 dir_ignore_fn,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
449 options,
44838
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
450 traversed_sender,
44539
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
451 )
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
452 .unwrap_or_else(|e| files_sender.send(Err(e)).unwrap())
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
453 }
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
454 });
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
455 }
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
456
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
457 /// Decides whether the directory needs to be listed, and if so handles the
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
458 /// entries in a separate thread.
44536
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
459 fn traverse_dir<'a>(
44539
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
460 files_sender: &crossbeam::Sender<IoResult<(HgPathBuf, Dispatch)>>,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
461 matcher: &'a (impl Matcher + Sync),
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
462 root_dir: impl AsRef<Path> + Sync + Send + Copy,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
463 dmap: &'a DirstateMap,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
464 directory: impl AsRef<HgPath>,
44536
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
465 old_results: &FastHashMap<Cow<'a, HgPath>, Dispatch>,
44597
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
466 ignore_fn: &IgnoreFnType,
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
467 dir_ignore_fn: &IgnoreFnType,
44527
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
468 options: StatusOptions,
44838
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
469 traversed_sender: crossbeam::Sender<HgPathBuf>,
44539
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
470 ) -> IoResult<()> {
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
471 let directory = directory.as_ref();
44748
a467416c493c rust-status: check for '.hg' regardless of file type (issue6300)
Raphaël Gomès <rgomes@octobus.net>
parents: 44747
diff changeset
472
44838
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
473 if options.collect_traversed_dirs {
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
474 // The receiver always outlives the sender, so unwrap.
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
475 traversed_sender.send(directory.to_owned()).unwrap()
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
476 }
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
477
44536
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
478 let visit_entries = match matcher.visit_children_set(directory) {
44539
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
479 VisitChildrenSet::Empty => return Ok(()),
44536
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
480 VisitChildrenSet::This | VisitChildrenSet::Recursive => None,
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
481 VisitChildrenSet::Set(set) => Some(set),
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
482 };
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
483 let buf = hg_path_to_path_buf(directory)?;
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
484 let dir_path = root_dir.as_ref().join(buf);
44527
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
485
44536
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
486 let skip_dot_hg = !directory.as_bytes().is_empty();
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
487 let entries = match list_directory(dir_path, skip_dot_hg) {
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
488 Err(e) => match e.kind() {
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
489 ErrorKind::NotFound | ErrorKind::PermissionDenied => {
44539
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
490 files_sender
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
491 .send(Ok((
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
492 directory.to_owned(),
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
493 Dispatch::Bad(BadMatch::OsError(
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
494 // Unwrapping here is OK because the error always
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
495 // is a real os error
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
496 e.raw_os_error().unwrap(),
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
497 )),
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
498 )))
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
499 .unwrap();
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
500 return Ok(());
44536
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
501 }
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
502 _ => return Err(e),
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
503 },
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
504 Ok(entries) => entries,
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
505 };
44527
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
506
44539
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
507 rayon::scope(|scope| -> IoResult<()> {
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
508 for (filename, dir_entry) in entries {
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
509 if let Some(ref set) = visit_entries {
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
510 if !set.contains(filename.deref()) {
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
511 continue;
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
512 }
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
513 }
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
514 // TODO normalize
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
515 let filename = if directory.is_empty() {
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
516 filename.to_owned()
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
517 } else {
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
518 directory.join(&filename)
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
519 };
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
520
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
521 if !old_results.contains_key(filename.deref()) {
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
522 handle_traversed_entry(
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
523 scope,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
524 files_sender,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
525 matcher,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
526 root_dir,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
527 dmap,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
528 old_results,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
529 ignore_fn,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
530 dir_ignore_fn,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
531 options,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
532 filename,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
533 dir_entry,
44838
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
534 traversed_sender.clone(),
44539
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
535 )?;
44536
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
536 }
44527
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
537 }
44539
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
538 Ok(())
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
539 })
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
540 }
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
541
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
542 /// Walk the working directory recursively to look for changes compared to the
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
543 /// current `DirstateMap`.
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
544 ///
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
545 /// This takes a mutable reference to the results to account for the `extend`
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
546 /// in timings
44541
d880805d5442 hg-core: add function timing information
Raphaël Gomès <rgomes@octobus.net>
parents: 44539
diff changeset
547 #[timed]
44539
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
548 fn traverse<'a>(
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
549 matcher: &'a (impl Matcher + Sync),
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
550 root_dir: impl AsRef<Path> + Sync + Send + Copy,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
551 dmap: &'a DirstateMap,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
552 path: impl AsRef<HgPath>,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
553 old_results: &FastHashMap<Cow<'a, HgPath>, Dispatch>,
44597
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
554 ignore_fn: &IgnoreFnType,
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
555 dir_ignore_fn: &IgnoreFnType,
44539
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
556 options: StatusOptions,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
557 results: &mut Vec<(Cow<'a, HgPath>, Dispatch)>,
44838
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
558 traversed_sender: crossbeam::Sender<HgPathBuf>,
44539
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
559 ) -> IoResult<()> {
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
560 let root_dir = root_dir.as_ref();
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
561
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
562 // The traversal is done in parallel, so use a channel to gather entries.
44925
ce8fe77102f4 rust: fix false comment about mpsc::Sender
Yuya Nishihara <yuya@tcha.org>
parents: 44842
diff changeset
563 // `crossbeam::Sender` is `Sync`, while `mpsc::Sender` is not.
44539
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
564 let (files_transmitter, files_receiver) = crossbeam::channel::unbounded();
44527
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
565
44539
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
566 traverse_dir(
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
567 &files_transmitter,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
568 matcher,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
569 root_dir,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
570 &dmap,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
571 path,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
572 &old_results,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
573 &ignore_fn,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
574 &dir_ignore_fn,
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
575 options,
44838
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
576 traversed_sender,
44539
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
577 )?;
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
578
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
579 // Disconnect the channel so the receiver stops waiting
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
580 drop(files_transmitter);
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
581
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
582 // TODO don't collect. Find a way of replicating the behavior of
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
583 // `itertools::process_results`, but for `rayon::ParallelIterator`
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
584 let new_results: IoResult<Vec<(Cow<'a, HgPath>, Dispatch)>> =
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
585 files_receiver
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
586 .into_iter()
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
587 .map(|item| {
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
588 let (f, d) = item?;
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
589 Ok((Cow::Owned(f), d))
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
590 })
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
591 .collect();
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
592
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
593 results.par_extend(new_results?);
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
594
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
595 Ok(())
44524
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
596 }
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
597
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
598 /// Stat all entries in the `DirstateMap` and mark them for dispatch.
43602
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
599 fn stat_dmap_entries(
43271
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
600 dmap: &DirstateMap,
43603
75fe6e71ddb8 rust-status: return a ParallelIterator instead of a Vec from stat_dmap_entries
Raphaël Gomès <rgomes@octobus.net>
parents: 43602
diff changeset
601 root_dir: impl AsRef<Path> + Sync + Send,
44524
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
602 options: StatusOptions,
43915
8c77826116f7 rust-dirstate-status: add `walk_explicit` implementation, use `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43818
diff changeset
603 ) -> impl ParallelIterator<Item = IoResult<(&HgPath, Dispatch)>> {
43603
75fe6e71ddb8 rust-status: return a ParallelIterator instead of a Vec from stat_dmap_entries
Raphaël Gomès <rgomes@octobus.net>
parents: 43602
diff changeset
604 dmap.par_iter().map(move |(filename, entry)| {
75fe6e71ddb8 rust-status: return a ParallelIterator instead of a Vec from stat_dmap_entries
Raphaël Gomès <rgomes@octobus.net>
parents: 43602
diff changeset
605 let filename: &HgPath = filename;
75fe6e71ddb8 rust-status: return a ParallelIterator instead of a Vec from stat_dmap_entries
Raphaël Gomès <rgomes@octobus.net>
parents: 43602
diff changeset
606 let filename_as_path = hg_path_to_path_buf(filename)?;
75fe6e71ddb8 rust-status: return a ParallelIterator instead of a Vec from stat_dmap_entries
Raphaël Gomès <rgomes@octobus.net>
parents: 43602
diff changeset
607 let meta = root_dir.as_ref().join(filename_as_path).symlink_metadata();
43271
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
608
43603
75fe6e71ddb8 rust-status: return a ParallelIterator instead of a Vec from stat_dmap_entries
Raphaël Gomès <rgomes@octobus.net>
parents: 43602
diff changeset
609 match meta {
75fe6e71ddb8 rust-status: return a ParallelIterator instead of a Vec from stat_dmap_entries
Raphaël Gomès <rgomes@octobus.net>
parents: 43602
diff changeset
610 Ok(ref m)
75fe6e71ddb8 rust-status: return a ParallelIterator instead of a Vec from stat_dmap_entries
Raphaël Gomès <rgomes@octobus.net>
parents: 43602
diff changeset
611 if !(m.file_type().is_file()
75fe6e71ddb8 rust-status: return a ParallelIterator instead of a Vec from stat_dmap_entries
Raphaël Gomès <rgomes@octobus.net>
parents: 43602
diff changeset
612 || m.file_type().is_symlink()) =>
75fe6e71ddb8 rust-status: return a ParallelIterator instead of a Vec from stat_dmap_entries
Raphaël Gomès <rgomes@octobus.net>
parents: 43602
diff changeset
613 {
75fe6e71ddb8 rust-status: return a ParallelIterator instead of a Vec from stat_dmap_entries
Raphaël Gomès <rgomes@octobus.net>
parents: 43602
diff changeset
614 Ok((filename, dispatch_missing(entry.state)))
75fe6e71ddb8 rust-status: return a ParallelIterator instead of a Vec from stat_dmap_entries
Raphaël Gomès <rgomes@octobus.net>
parents: 43602
diff changeset
615 }
75fe6e71ddb8 rust-status: return a ParallelIterator instead of a Vec from stat_dmap_entries
Raphaël Gomès <rgomes@octobus.net>
parents: 43602
diff changeset
616 Ok(m) => Ok((
75fe6e71ddb8 rust-status: return a ParallelIterator instead of a Vec from stat_dmap_entries
Raphaël Gomès <rgomes@octobus.net>
parents: 43602
diff changeset
617 filename,
75fe6e71ddb8 rust-status: return a ParallelIterator instead of a Vec from stat_dmap_entries
Raphaël Gomès <rgomes@octobus.net>
parents: 43602
diff changeset
618 dispatch_found(
75fe6e71ddb8 rust-status: return a ParallelIterator instead of a Vec from stat_dmap_entries
Raphaël Gomès <rgomes@octobus.net>
parents: 43602
diff changeset
619 filename,
75fe6e71ddb8 rust-status: return a ParallelIterator instead of a Vec from stat_dmap_entries
Raphaël Gomès <rgomes@octobus.net>
parents: 43602
diff changeset
620 *entry,
75fe6e71ddb8 rust-status: return a ParallelIterator instead of a Vec from stat_dmap_entries
Raphaël Gomès <rgomes@octobus.net>
parents: 43602
diff changeset
621 HgMetadata::from_metadata(m),
75fe6e71ddb8 rust-status: return a ParallelIterator instead of a Vec from stat_dmap_entries
Raphaël Gomès <rgomes@octobus.net>
parents: 43602
diff changeset
622 &dmap.copy_map,
44524
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
623 options,
43603
75fe6e71ddb8 rust-status: return a ParallelIterator instead of a Vec from stat_dmap_entries
Raphaël Gomès <rgomes@octobus.net>
parents: 43602
diff changeset
624 ),
75fe6e71ddb8 rust-status: return a ParallelIterator instead of a Vec from stat_dmap_entries
Raphaël Gomès <rgomes@octobus.net>
parents: 43602
diff changeset
625 )),
75fe6e71ddb8 rust-status: return a ParallelIterator instead of a Vec from stat_dmap_entries
Raphaël Gomès <rgomes@octobus.net>
parents: 43602
diff changeset
626 Err(ref e)
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
627 if e.kind() == ErrorKind::NotFound
43603
75fe6e71ddb8 rust-status: return a ParallelIterator instead of a Vec from stat_dmap_entries
Raphaël Gomès <rgomes@octobus.net>
parents: 43602
diff changeset
628 || e.raw_os_error() == Some(20) =>
75fe6e71ddb8 rust-status: return a ParallelIterator instead of a Vec from stat_dmap_entries
Raphaël Gomès <rgomes@octobus.net>
parents: 43602
diff changeset
629 {
75fe6e71ddb8 rust-status: return a ParallelIterator instead of a Vec from stat_dmap_entries
Raphaël Gomès <rgomes@octobus.net>
parents: 43602
diff changeset
630 // Rust does not yet have an `ErrorKind` for
75fe6e71ddb8 rust-status: return a ParallelIterator instead of a Vec from stat_dmap_entries
Raphaël Gomès <rgomes@octobus.net>
parents: 43602
diff changeset
631 // `NotADirectory` (errno 20)
75fe6e71ddb8 rust-status: return a ParallelIterator instead of a Vec from stat_dmap_entries
Raphaël Gomès <rgomes@octobus.net>
parents: 43602
diff changeset
632 // It happens if the dirstate contains `foo/bar` and
75fe6e71ddb8 rust-status: return a ParallelIterator instead of a Vec from stat_dmap_entries
Raphaël Gomès <rgomes@octobus.net>
parents: 43602
diff changeset
633 // foo is not a directory
75fe6e71ddb8 rust-status: return a ParallelIterator instead of a Vec from stat_dmap_entries
Raphaël Gomès <rgomes@octobus.net>
parents: 43602
diff changeset
634 Ok((filename, dispatch_missing(entry.state)))
75fe6e71ddb8 rust-status: return a ParallelIterator instead of a Vec from stat_dmap_entries
Raphaël Gomès <rgomes@octobus.net>
parents: 43602
diff changeset
635 }
75fe6e71ddb8 rust-status: return a ParallelIterator instead of a Vec from stat_dmap_entries
Raphaël Gomès <rgomes@octobus.net>
parents: 43602
diff changeset
636 Err(e) => Err(e),
75fe6e71ddb8 rust-status: return a ParallelIterator instead of a Vec from stat_dmap_entries
Raphaël Gomès <rgomes@octobus.net>
parents: 43602
diff changeset
637 }
75fe6e71ddb8 rust-status: return a ParallelIterator instead of a Vec from stat_dmap_entries
Raphaël Gomès <rgomes@octobus.net>
parents: 43602
diff changeset
638 })
43271
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
639 }
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
640
44538
b8ba46c97cdd rust-status: wrap `stat_dmap_entries` to ease profiling
Raphaël Gomès <rgomes@octobus.net>
parents: 44537
diff changeset
641 /// This takes a mutable reference to the results to account for the `extend`
b8ba46c97cdd rust-status: wrap `stat_dmap_entries` to ease profiling
Raphaël Gomès <rgomes@octobus.net>
parents: 44537
diff changeset
642 /// in timings
44541
d880805d5442 hg-core: add function timing information
Raphaël Gomès <rgomes@octobus.net>
parents: 44539
diff changeset
643 #[timed]
44538
b8ba46c97cdd rust-status: wrap `stat_dmap_entries` to ease profiling
Raphaël Gomès <rgomes@octobus.net>
parents: 44537
diff changeset
644 fn extend_from_dmap<'a>(
b8ba46c97cdd rust-status: wrap `stat_dmap_entries` to ease profiling
Raphaël Gomès <rgomes@octobus.net>
parents: 44537
diff changeset
645 dmap: &'a DirstateMap,
b8ba46c97cdd rust-status: wrap `stat_dmap_entries` to ease profiling
Raphaël Gomès <rgomes@octobus.net>
parents: 44537
diff changeset
646 root_dir: impl AsRef<Path> + Sync + Send,
b8ba46c97cdd rust-status: wrap `stat_dmap_entries` to ease profiling
Raphaël Gomès <rgomes@octobus.net>
parents: 44537
diff changeset
647 options: StatusOptions,
b8ba46c97cdd rust-status: wrap `stat_dmap_entries` to ease profiling
Raphaël Gomès <rgomes@octobus.net>
parents: 44537
diff changeset
648 results: &mut Vec<(Cow<'a, HgPath>, Dispatch)>,
b8ba46c97cdd rust-status: wrap `stat_dmap_entries` to ease profiling
Raphaël Gomès <rgomes@octobus.net>
parents: 44537
diff changeset
649 ) {
b8ba46c97cdd rust-status: wrap `stat_dmap_entries` to ease profiling
Raphaël Gomès <rgomes@octobus.net>
parents: 44537
diff changeset
650 results.par_extend(
b8ba46c97cdd rust-status: wrap `stat_dmap_entries` to ease profiling
Raphaël Gomès <rgomes@octobus.net>
parents: 44537
diff changeset
651 stat_dmap_entries(dmap, root_dir, options)
b8ba46c97cdd rust-status: wrap `stat_dmap_entries` to ease profiling
Raphaël Gomès <rgomes@octobus.net>
parents: 44537
diff changeset
652 .flatten()
b8ba46c97cdd rust-status: wrap `stat_dmap_entries` to ease profiling
Raphaël Gomès <rgomes@octobus.net>
parents: 44537
diff changeset
653 .map(|(filename, dispatch)| (Cow::Borrowed(filename), dispatch)),
b8ba46c97cdd rust-status: wrap `stat_dmap_entries` to ease profiling
Raphaël Gomès <rgomes@octobus.net>
parents: 44537
diff changeset
654 );
b8ba46c97cdd rust-status: wrap `stat_dmap_entries` to ease profiling
Raphaël Gomès <rgomes@octobus.net>
parents: 44537
diff changeset
655 }
b8ba46c97cdd rust-status: wrap `stat_dmap_entries` to ease profiling
Raphaël Gomès <rgomes@octobus.net>
parents: 44537
diff changeset
656
44562
ece43c79333e rust-core: add missing `Debug` traits
Raphaël Gomès <rgomes@octobus.net>
parents: 44541
diff changeset
657 #[derive(Debug)]
44525
f13d19549efd rust-status: rename `StatusResult` to `DirstateStatus`
Raphaël Gomès <rgomes@octobus.net>
parents: 44524
diff changeset
658 pub struct DirstateStatus<'a> {
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
659 pub modified: Vec<Cow<'a, HgPath>>,
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
660 pub added: Vec<Cow<'a, HgPath>>,
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
661 pub removed: Vec<Cow<'a, HgPath>>,
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
662 pub deleted: Vec<Cow<'a, HgPath>>,
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
663 pub clean: Vec<Cow<'a, HgPath>>,
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
664 pub ignored: Vec<Cow<'a, HgPath>>,
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
665 pub unknown: Vec<Cow<'a, HgPath>>,
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
666 pub bad: Vec<(Cow<'a, HgPath>, BadMatch)>,
44838
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
667 /// Only filled if `collect_traversed_dirs` is `true`
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
668 pub traversed: Vec<HgPathBuf>,
43271
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
669 }
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
670
44541
d880805d5442 hg-core: add function timing information
Raphaël Gomès <rgomes@octobus.net>
parents: 44539
diff changeset
671 #[timed]
43915
8c77826116f7 rust-dirstate-status: add `walk_explicit` implementation, use `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43818
diff changeset
672 fn build_response<'a>(
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
673 results: impl IntoIterator<Item = (Cow<'a, HgPath>, Dispatch)>,
44838
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
674 traversed: Vec<HgPathBuf>,
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
675 ) -> (Vec<Cow<'a, HgPath>>, DirstateStatus<'a>) {
43271
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
676 let mut lookup = vec![];
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
677 let mut modified = vec![];
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
678 let mut added = vec![];
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
679 let mut removed = vec![];
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
680 let mut deleted = vec![];
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
681 let mut clean = vec![];
44526
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
682 let mut ignored = vec![];
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
683 let mut unknown = vec![];
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
684 let mut bad = vec![];
43271
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
685
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
686 for (filename, dispatch) in results.into_iter() {
43602
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
687 match dispatch {
44526
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
688 Dispatch::Unknown => unknown.push(filename),
43602
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
689 Dispatch::Unsure => lookup.push(filename),
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
690 Dispatch::Modified => modified.push(filename),
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
691 Dispatch::Added => added.push(filename),
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
692 Dispatch::Removed => removed.push(filename),
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
693 Dispatch::Deleted => deleted.push(filename),
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
694 Dispatch::Clean => clean.push(filename),
44526
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
695 Dispatch::Ignored => ignored.push(filename),
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
696 Dispatch::None => {}
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
697 Dispatch::Bad(reason) => bad.push((filename, reason)),
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
698 Dispatch::Directory { .. } => {}
43271
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
699 }
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
700 }
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
701
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
702 (
43271
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
703 lookup,
44525
f13d19549efd rust-status: rename `StatusResult` to `DirstateStatus`
Raphaël Gomès <rgomes@octobus.net>
parents: 44524
diff changeset
704 DirstateStatus {
43271
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
705 modified,
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
706 added,
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
707 removed,
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
708 deleted,
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
709 clean,
44526
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
710 ignored,
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
711 unknown,
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
712 bad,
44838
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
713 traversed,
43271
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
714 },
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
715 )
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
716 }
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
717
44562
ece43c79333e rust-core: add missing `Debug` traits
Raphaël Gomès <rgomes@octobus.net>
parents: 44541
diff changeset
718 #[derive(Debug)]
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
719 pub enum StatusError {
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
720 IO(std::io::Error),
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
721 Path(HgPathError),
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
722 Pattern(PatternError),
43271
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
723 }
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
724
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
725 pub type StatusResult<T> = Result<T, StatusError>;
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
726
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
727 impl From<PatternError> for StatusError {
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
728 fn from(e: PatternError) -> Self {
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
729 StatusError::Pattern(e)
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
730 }
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
731 }
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
732 impl From<HgPathError> for StatusError {
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
733 fn from(e: HgPathError) -> Self {
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
734 StatusError::Path(e)
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
735 }
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
736 }
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
737 impl From<std::io::Error> for StatusError {
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
738 fn from(e: std::io::Error) -> Self {
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
739 StatusError::IO(e)
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
740 }
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
741 }
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
742
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
743 impl ToString for StatusError {
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
744 fn to_string(&self) -> String {
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
745 match self {
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
746 StatusError::IO(e) => e.to_string(),
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
747 StatusError::Path(e) => e.to_string(),
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
748 StatusError::Pattern(e) => e.to_string(),
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
749 }
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
750 }
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
751 }
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
752
44537
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
753 /// This takes a mutable reference to the results to account for the `extend`
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
754 /// in timings
44541
d880805d5442 hg-core: add function timing information
Raphaël Gomès <rgomes@octobus.net>
parents: 44539
diff changeset
755 #[timed]
44537
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
756 fn handle_unknowns<'a>(
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
757 dmap: &'a DirstateMap,
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
758 matcher: &(impl Matcher + Sync),
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
759 root_dir: impl AsRef<Path> + Sync + Send + Copy,
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
760 options: StatusOptions,
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
761 results: &mut Vec<(Cow<'a, HgPath>, Dispatch)>,
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
762 ) -> IoResult<()> {
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
763 let to_visit: Vec<(&HgPath, &DirstateEntry)> = if results.is_empty()
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
764 && matcher.matches_everything()
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
765 {
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
766 dmap.iter().map(|(f, e)| (f.deref(), e)).collect()
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
767 } else {
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
768 // Only convert to a hashmap if needed.
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
769 let old_results: FastHashMap<_, _> = results.iter().cloned().collect();
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
770 dmap.iter()
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
771 .filter_map(move |(f, e)| {
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
772 if !old_results.contains_key(f.deref()) && matcher.matches(f) {
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
773 Some((f.deref(), e))
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
774 } else {
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
775 None
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
776 }
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
777 })
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
778 .collect()
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
779 };
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
780
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
781 // We walked all dirs under the roots that weren't ignored, and
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
782 // everything that matched was stat'ed and is already in results.
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
783 // The rest must thus be ignored or under a symlink.
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
784 let path_auditor = PathAuditor::new(root_dir);
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
785
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
786 // TODO don't collect. Find a way of replicating the behavior of
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
787 // `itertools::process_results`, but for `rayon::ParallelIterator`
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
788 let new_results: IoResult<Vec<_>> = to_visit
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
789 .into_par_iter()
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
790 .filter_map(|(filename, entry)| -> Option<IoResult<_>> {
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
791 // Report ignored items in the dmap as long as they are not
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
792 // under a symlink directory.
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
793 if path_auditor.check(filename) {
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
794 // TODO normalize for case-insensitive filesystems
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
795 let buf = match hg_path_to_path_buf(filename) {
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
796 Ok(x) => x,
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
797 Err(e) => return Some(Err(e.into())),
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
798 };
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
799 Some(Ok((
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
800 Cow::Borrowed(filename),
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
801 match root_dir.as_ref().join(&buf).symlink_metadata() {
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
802 // File was just ignored, no links, and exists
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
803 Ok(meta) => {
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
804 let metadata = HgMetadata::from_metadata(meta);
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
805 dispatch_found(
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
806 filename,
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
807 *entry,
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
808 metadata,
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
809 &dmap.copy_map,
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
810 options,
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
811 )
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
812 }
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
813 // File doesn't exist
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
814 Err(_) => dispatch_missing(entry.state),
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
815 },
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
816 )))
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
817 } else {
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
818 // It's either missing or under a symlink directory which
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
819 // we, in this case, report as missing.
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
820 Some(Ok((
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
821 Cow::Borrowed(filename),
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
822 dispatch_missing(entry.state),
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
823 )))
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
824 }
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
825 })
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
826 .collect();
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
827
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
828 results.par_extend(new_results?);
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
829
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
830 Ok(())
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
831 }
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
832
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
833 /// Get the status of files in the working directory.
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
834 ///
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
835 /// This is the current entry-point for `hg-core` and is realistically unusable
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
836 /// outside of a Python context because its arguments need to provide a lot of
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
837 /// information that will not be necessary in the future.
44541
d880805d5442 hg-core: add function timing information
Raphaël Gomès <rgomes@octobus.net>
parents: 44539
diff changeset
838 #[timed]
43915
8c77826116f7 rust-dirstate-status: add `walk_explicit` implementation, use `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43818
diff changeset
839 pub fn status<'a: 'c, 'b: 'c, 'c>(
8c77826116f7 rust-dirstate-status: add `walk_explicit` implementation, use `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43818
diff changeset
840 dmap: &'a DirstateMap,
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
841 matcher: &'b (impl Matcher + Sync),
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
842 root_dir: impl AsRef<Path> + Sync + Send + Copy + 'c,
44597
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
843 ignore_files: Vec<PathBuf>,
44524
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
844 options: StatusOptions,
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
845 ) -> StatusResult<(
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
846 (Vec<Cow<'c, HgPath>>, DirstateStatus<'c>),
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
847 Vec<PatternFileWarning>,
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
848 )> {
44597
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
849 // Needs to outlive `dir_ignore_fn` since it's captured.
44842
73d6ce2746d2 rust: fix warning about unnecessary mut
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 44838
diff changeset
850 let ignore_fn: IgnoreFnType;
44597
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
851
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
852 // Only involve real ignore mechanism if we're listing unknowns or ignored.
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
853 let (dir_ignore_fn, warnings): (IgnoreFnType, _) = if options.list_ignored
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
854 || options.list_unknown
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
855 {
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
856 let (ignore, warnings) = get_ignore_function(ignore_files, root_dir)?;
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
857
44597
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
858 ignore_fn = ignore;
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
859 let dir_ignore_fn = Box::new(|dir: &_| {
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
860 // Is the path or one of its ancestors ignored?
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
861 if ignore_fn(dir) {
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
862 true
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
863 } else {
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
864 for p in find_dirs(dir) {
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
865 if ignore_fn(p) {
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
866 return true;
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
867 }
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
868 }
44597
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
869 false
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
870 }
44597
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
871 });
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
872 (dir_ignore_fn, warnings)
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
873 } else {
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
874 ignore_fn = Box::new(|&_| true);
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
875 (Box::new(|&_| true), vec![])
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
876 };
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
877
43915
8c77826116f7 rust-dirstate-status: add `walk_explicit` implementation, use `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43818
diff changeset
878 let files = matcher.file_set();
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
879
44925
ce8fe77102f4 rust: fix false comment about mpsc::Sender
Yuya Nishihara <yuya@tcha.org>
parents: 44842
diff changeset
880 // `crossbeam::Sender` is `Sync`, while `mpsc::Sender` is not.
44838
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
881 let (traversed_sender, traversed_recv) = crossbeam::channel::unbounded();
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
882
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
883 // Step 1: check the files explicitly mentioned by the user
44838
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
884 let explicit = walk_explicit(
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
885 files,
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
886 &dmap,
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
887 root_dir,
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
888 options,
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
889 traversed_sender.clone(),
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
890 );
44536
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
891
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
892 // Collect results into a `Vec` because we do very few lookups in most
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
893 // cases.
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
894 let (work, mut results): (Vec<_>, Vec<_>) = explicit
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
895 .filter_map(Result::ok)
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
896 .map(|(filename, dispatch)| (Cow::Borrowed(filename), dispatch))
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
897 .partition(|(_, dispatch)| match dispatch {
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
898 Dispatch::Directory { .. } => true,
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
899 _ => false,
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
900 });
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
901
44536
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
902 if !work.is_empty() {
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
903 // Hashmaps are quite a bit slower to build than vecs, so only build it
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
904 // if needed.
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
905 let old_results = results.iter().cloned().collect();
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
906
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
907 // Step 2: recursively check the working directory for changes if
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
908 // needed
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
909 for (dir, dispatch) in work {
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
910 match dispatch {
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
911 Dispatch::Directory { was_file } => {
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
912 if was_file {
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
913 results.push((dir.to_owned(), Dispatch::Removed));
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
914 }
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
915 if options.list_ignored
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
916 || options.list_unknown && !dir_ignore_fn(&dir)
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
917 {
44539
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
918 traverse(
44536
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
919 matcher,
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
920 root_dir,
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
921 &dmap,
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
922 &dir,
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
923 &old_results,
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
924 &ignore_fn,
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
925 &dir_ignore_fn,
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
926 options,
44539
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
927 &mut results,
44838
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
928 traversed_sender.clone(),
44539
fe7d2cf0b429 rust-status: traverse working directory in parallel
Raphaël Gomès <rgomes@octobus.net>
parents: 44538
diff changeset
929 )?;
44536
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
930 }
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
931 }
44536
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
932 _ => unreachable!("There can only be directories in `work`"),
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
933 }
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
934 }
43915
8c77826116f7 rust-dirstate-status: add `walk_explicit` implementation, use `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43818
diff changeset
935 }
43602
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
936
43915
8c77826116f7 rust-dirstate-status: add `walk_explicit` implementation, use `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43818
diff changeset
937 if !matcher.is_exact() {
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
938 // Step 3: Check the remaining files from the dmap.
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
939 // If a dmap file is not in results yet, it was either
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
940 // a) not matched b) ignored, c) missing, or d) under a
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
941 // symlink directory.
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
942
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
943 if options.list_unknown {
44537
5f6a504dc0bd rust-status: refactor handling of unknown files
Raphaël Gomès <rgomes@octobus.net>
parents: 44536
diff changeset
944 handle_unknowns(dmap, matcher, root_dir, options, &mut results)?;
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
945 } else {
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
946 // We may not have walked the full directory tree above, so stat
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
947 // and check everything we missed.
44538
b8ba46c97cdd rust-status: wrap `stat_dmap_entries` to ease profiling
Raphaël Gomès <rgomes@octobus.net>
parents: 44537
diff changeset
948 extend_from_dmap(&dmap, root_dir, options, &mut results);
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
949 }
43915
8c77826116f7 rust-dirstate-status: add `walk_explicit` implementation, use `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43818
diff changeset
950 }
8c77826116f7 rust-dirstate-status: add `walk_explicit` implementation, use `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43818
diff changeset
951
44838
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
952 // Close the channel
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
953 drop(traversed_sender);
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
954 let traversed_dirs = traversed_recv.into_iter().collect();
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
955
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
956 Ok((build_response(results, traversed_dirs), warnings))
43271
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
957 }