annotate rust/hg-core/src/dirstate/status.rs @ 46890:441024b279a6

rust: Remove the compile-time 'dirstate-tree' feature flag This code has compiler errors since it is not built on CI and nobody has been working on it for some time. We (Octobus) are still pursuing status optimizations based on a tree data structure for the dirstate, but upcoming patches will use a run-time opt-in instead of compile-time, so that at least corresponding Rust code keeps compiling when other changes are made. Differential Revision: https://phab.mercurial-scm.org/D10329
author Simon Sapin <simon.sapin@octobus.net>
date Thu, 08 Apr 2021 21:46:54 +0200
parents 3c9ddb1986a9
children 787ff5d21bcd c8f62920f07a
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
45610
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
12 use crate::utils::path_auditor::PathAuditor;
43605
8210c3f46912 rust: introduce SIZE_FROM_OTHER_PARENT constant
Raphaël Gomès <rgomes@octobus.net>
parents: 43604
diff changeset
13 use crate::{
8210c3f46912 rust: introduce SIZE_FROM_OTHER_PARENT constant
Raphaël Gomès <rgomes@octobus.net>
parents: 43604
diff changeset
14 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
15 filepatterns::PatternFileWarning,
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
16 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
17 utils::{
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
18 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
19 hg_path::{
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
20 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
21 HgPathError,
44523
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
22 },
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,
46444
6c778d20c8c2 rust: replace ToString impls with Display
Simon Sapin <simon.sapin@octobus.net>
parents: 46435
diff changeset
33 fmt,
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
34 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
35 io::ErrorKind,
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
36 ops::Deref,
44597
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
37 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
38 };
43271
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
39
44526
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
40 /// 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
41 /// 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
42 #[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
43 pub enum BadType {
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
44 CharacterDevice,
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
45 BlockDevice,
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
46 FIFO,
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
47 Socket,
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
48 Directory,
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
49 Unknown,
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
50 }
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
51
46444
6c778d20c8c2 rust: replace ToString impls with Display
Simon Sapin <simon.sapin@octobus.net>
parents: 46435
diff changeset
52 impl fmt::Display for BadType {
6c778d20c8c2 rust: replace ToString impls with Display
Simon Sapin <simon.sapin@octobus.net>
parents: 46435
diff changeset
53 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6c778d20c8c2 rust: replace ToString impls with Display
Simon Sapin <simon.sapin@octobus.net>
parents: 46435
diff changeset
54 f.write_str(match self {
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
55 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
56 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
57 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
58 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
59 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
60 BadType::Unknown => "unknown",
46444
6c778d20c8c2 rust: replace ToString impls with Display
Simon Sapin <simon.sapin@octobus.net>
parents: 46435
diff changeset
61 })
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
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
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
72 /// Enum used to dispatch new status entries into the right collections.
43602
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)]
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
76 pub enum Dispatch {
43602
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>;
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
97
44597
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
98 /// `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
99 /// 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
100 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
101
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
102 /// We have a good mix of owned (from directory traversal) and borrowed (from
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
103 /// the dirstate/explicit) paths, this comes up a lot.
45113
98817e5daca7 hg-core: define a `dirstate_status` `Operation`
Raphaël Gomès <rgomes@octobus.net>
parents: 45112
diff changeset
104 pub type HgPathCow<'a> = Cow<'a, HgPath>;
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
105
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
106 /// A path with its computed ``Dispatch`` information
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
107 type DispatchedPath<'a> = (HgPathCow<'a>, Dispatch);
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
108
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
109 /// The conversion from `HgPath` to a real fs path failed.
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
110 /// `22` is the error code for "Invalid argument"
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
111 const INVALID_PATH_DISPATCH: Dispatch = Dispatch::Bad(BadMatch::OsError(22));
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
112
43604
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
113 /// 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
114 /// 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
115 /// 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
116 /// changes. (issue2608)
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
117 /// 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
118 /// 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
119 /// 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
120 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
121 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
122 }
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
123
44523
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
124 /// 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
125 /// in the directory.
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
126 ///
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
127 /// * `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
128 fn list_directory(
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
129 path: impl AsRef<Path>,
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
130 skip_dot_hg: bool,
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
131 ) -> 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
132 let mut results = vec![];
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
133 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
134
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
135 for entry in entries {
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
136 let entry = entry?;
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
137 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
138 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
139 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
140 return Ok(vec![]);
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
141 } else {
44973
26114bd6ec60 rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents: 44926
diff changeset
142 results.push((filename, entry))
44523
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
143 }
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
144 }
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
145
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
146 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
147 Ok(results)
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
148 }
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
149
43602
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
150 /// 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
151 fn dispatch_found(
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
152 filename: impl AsRef<HgPath>,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
153 entry: DirstateEntry,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
154 metadata: HgMetadata,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
155 copy_map: &CopyMap,
44524
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
156 options: StatusOptions,
43602
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
157 ) -> Dispatch {
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
158 let DirstateEntry {
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
159 state,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
160 mode,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
161 mtime,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
162 size,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
163 } = entry;
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
164
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
165 let HgMetadata {
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
166 st_mode,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
167 st_size,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
168 st_mtime,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
169 ..
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
170 } = metadata;
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
171
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
172 match state {
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
173 EntryState::Normal => {
43604
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
174 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
175 let mode_changed =
44524
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
176 (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
177 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
178 let other_parent = size == SIZE_FROM_OTHER_PARENT;
44973
26114bd6ec60 rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents: 44926
diff changeset
179
43604
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
180 if metadata_changed
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
181 || other_parent
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
182 || 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
183 {
46757
3c9ddb1986a9 rust-status: fix issue6456 for the Rust implementation also
Raphaël Gomès <rgomes@octobus.net>
parents: 46494
diff changeset
184 if metadata.is_symlink() && size_changed {
3c9ddb1986a9 rust-status: fix issue6456 for the Rust implementation also
Raphaël Gomès <rgomes@octobus.net>
parents: 46494
diff changeset
185 // issue6456: Size returned may be longer due to encryption
3c9ddb1986a9 rust-status: fix issue6456 for the Rust implementation also
Raphaël Gomès <rgomes@octobus.net>
parents: 46494
diff changeset
186 // on EXT-4 fscrypt. TODO maybe only do it on EXT4?
3c9ddb1986a9 rust-status: fix issue6456 for the Rust implementation also
Raphaël Gomès <rgomes@octobus.net>
parents: 46494
diff changeset
187 Dispatch::Unsure
3c9ddb1986a9 rust-status: fix issue6456 for the Rust implementation also
Raphaël Gomès <rgomes@octobus.net>
parents: 46494
diff changeset
188 } else {
3c9ddb1986a9 rust-status: fix issue6456 for the Rust implementation also
Raphaël Gomès <rgomes@octobus.net>
parents: 46494
diff changeset
189 Dispatch::Modified
3c9ddb1986a9 rust-status: fix issue6456 for the Rust implementation also
Raphaël Gomès <rgomes@octobus.net>
parents: 46494
diff changeset
190 }
44973
26114bd6ec60 rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents: 44926
diff changeset
191 } else if mod_compare(mtime, st_mtime as i32)
26114bd6ec60 rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents: 44926
diff changeset
192 || st_mtime == options.last_normal_time
26114bd6ec60 rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents: 44926
diff changeset
193 {
43602
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
194 // 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
195 // 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
196 // 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
197 // 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
198 // miss such a racy file change.
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
199 Dispatch::Unsure
44524
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
200 } else if options.list_clean {
43602
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
201 Dispatch::Clean
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
202 } else {
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
203 Dispatch::None
43602
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
204 }
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 EntryState::Merged => Dispatch::Modified,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
207 EntryState::Added => Dispatch::Added,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
208 EntryState::Removed => Dispatch::Removed,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
209 EntryState::Unknown => Dispatch::Unknown,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
210 }
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
211 }
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
212
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
213 /// 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
214 fn dispatch_missing(state: EntryState) -> Dispatch {
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
215 match state {
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
216 // 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
217 EntryState::Normal | EntryState::Merged | EntryState::Added => {
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
218 Dispatch::Deleted
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
219 }
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
220 // File was removed, everything is normal
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
221 EntryState::Removed => Dispatch::Removed,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
222 // 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
223 EntryState::Unknown => Dispatch::Unknown,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
224 }
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
225 }
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
226
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
227 fn dispatch_os_error(e: &std::io::Error) -> Dispatch {
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
228 Dispatch::Bad(BadMatch::OsError(
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
229 e.raw_os_error().expect("expected real OS error"),
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
230 ))
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
231 }
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
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 lazy_static! {
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
234 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
235 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
236 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
237 h
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
238 };
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
239 }
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
240
44524
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
241 #[derive(Debug, Copy, Clone)]
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
242 pub struct StatusOptions {
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
243 /// 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
244 /// 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
245 /// 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
246 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
247 /// 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
248 pub check_exec: bool,
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
249 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
250 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
251 pub list_ignored: bool,
44838
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
252 /// 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
253 /// 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
254 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
255 }
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
256
44562
ece43c79333e rust-core: add missing `Debug` traits
Raphaël Gomès <rgomes@octobus.net>
parents: 44541
diff changeset
257 #[derive(Debug)]
44525
f13d19549efd rust-status: rename `StatusResult` to `DirstateStatus`
Raphaël Gomès <rgomes@octobus.net>
parents: 44524
diff changeset
258 pub struct DirstateStatus<'a> {
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
259 pub modified: Vec<HgPathCow<'a>>,
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
260 pub added: Vec<HgPathCow<'a>>,
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
261 pub removed: Vec<HgPathCow<'a>>,
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
262 pub deleted: Vec<HgPathCow<'a>>,
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
263 pub clean: Vec<HgPathCow<'a>>,
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
264 pub ignored: Vec<HgPathCow<'a>>,
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
265 pub unknown: Vec<HgPathCow<'a>>,
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
266 pub bad: Vec<(HgPathCow<'a>, BadMatch)>,
44838
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
267 /// 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
268 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
269 }
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
270
46435
2e2033081274 rust: replace trivial `impl From …` with `#[derive(derive_more::From)]`
Simon Sapin <simon.sapin@octobus.net>
parents: 46054
diff changeset
271 #[derive(Debug, derive_more::From)]
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
272 pub enum StatusError {
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
273 /// Generic IO error
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
274 IO(std::io::Error),
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
275 /// An invalid path that cannot be represented in Mercurial was found
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
276 Path(HgPathError),
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
277 /// An invalid "ignore" pattern was found
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
278 Pattern(PatternError),
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
279 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
280
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
281 pub type StatusResult<T> = Result<T, StatusError>;
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
282
46444
6c778d20c8c2 rust: replace ToString impls with Display
Simon Sapin <simon.sapin@octobus.net>
parents: 46435
diff changeset
283 impl fmt::Display for StatusError {
6c778d20c8c2 rust: replace ToString impls with Display
Simon Sapin <simon.sapin@octobus.net>
parents: 46435
diff changeset
284 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
285 match self {
46444
6c778d20c8c2 rust: replace ToString impls with Display
Simon Sapin <simon.sapin@octobus.net>
parents: 46435
diff changeset
286 StatusError::IO(error) => error.fmt(f),
6c778d20c8c2 rust: replace ToString impls with Display
Simon Sapin <simon.sapin@octobus.net>
parents: 46435
diff changeset
287 StatusError::Path(error) => error.fmt(f),
6c778d20c8c2 rust: replace ToString impls with Display
Simon Sapin <simon.sapin@octobus.net>
parents: 46435
diff changeset
288 StatusError::Pattern(error) => error.fmt(f),
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
289 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
290 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
291 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
292
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
293 /// Gives information about which files are changed in the working directory
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
294 /// and how, compared to the revision we're based on
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
295 pub struct Status<'a, M: Matcher + Sync> {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
296 dmap: &'a DirstateMap,
45113
98817e5daca7 hg-core: define a `dirstate_status` `Operation`
Raphaël Gomès <rgomes@octobus.net>
parents: 45112
diff changeset
297 pub(crate) matcher: &'a M,
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
298 root_dir: PathBuf,
45113
98817e5daca7 hg-core: define a `dirstate_status` `Operation`
Raphaël Gomès <rgomes@octobus.net>
parents: 45112
diff changeset
299 pub(crate) options: StatusOptions,
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
300 ignore_fn: IgnoreFnType<'a>,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
301 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
302
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
303 impl<'a, M> Status<'a, M>
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
304 where
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
305 M: Matcher + Sync,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
306 {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
307 pub fn new(
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
308 dmap: &'a DirstateMap,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
309 matcher: &'a M,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
310 root_dir: PathBuf,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
311 ignore_files: Vec<PathBuf>,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
312 options: StatusOptions,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
313 ) -> StatusResult<(Self, Vec<PatternFileWarning>)> {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
314 // Needs to outlive `dir_ignore_fn` since it's captured.
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
315
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
316 let (ignore_fn, warnings): (IgnoreFnType, _) =
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
317 if options.list_ignored || options.list_unknown {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
318 get_ignore_function(ignore_files, &root_dir)?
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
319 } else {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
320 (Box::new(|&_| true), vec![])
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
321 };
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
322
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
323 Ok((
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
324 Self {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
325 dmap,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
326 matcher,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
327 root_dir,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
328 options,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
329 ignore_fn,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
330 },
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
331 warnings,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
332 ))
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
333 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
334
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
335 /// Is the path ignored?
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
336 pub fn is_ignored(&self, path: impl AsRef<HgPath>) -> bool {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
337 (self.ignore_fn)(path.as_ref())
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
338 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
339
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
340 /// Is the path or one of its ancestors ignored?
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
341 pub fn dir_ignore(&self, dir: impl AsRef<HgPath>) -> bool {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
342 // Only involve ignore mechanism if we're listing unknowns or ignored.
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
343 if self.options.list_ignored || self.options.list_unknown {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
344 if self.is_ignored(&dir) {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
345 true
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
346 } else {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
347 for p in find_dirs(dir.as_ref()) {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
348 if self.is_ignored(p) {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
349 return true;
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
350 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
351 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
352 false
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
353 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
354 } else {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
355 true
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
356 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
357 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
358
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
359 /// Get stat data about the files explicitly specified by the matcher.
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
360 /// Returns a tuple of the directories that need to be traversed and the
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
361 /// files with their corresponding `Dispatch`.
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
362 /// TODO subrepos
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
363 #[timed]
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
364 pub fn walk_explicit(
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
365 &self,
46054
fd47483f1645 rust: use crossbeam-channel crate directly
Simon Sapin <simon-commits@exyr.org>
parents: 45862
diff changeset
366 traversed_sender: crossbeam_channel::Sender<HgPathBuf>,
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
367 ) -> (Vec<DispatchedPath<'a>>, Vec<DispatchedPath<'a>>) {
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
368 self.matcher
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
369 .file_set()
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
370 .unwrap_or(&DEFAULT_WORK)
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
371 .par_iter()
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
372 .flat_map(|&filename| -> Option<_> {
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
373 // TODO normalization
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
374 let normalized = filename;
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
375
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
376 let buf = match hg_path_to_path_buf(normalized) {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
377 Ok(x) => x,
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
378 Err(_) => {
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
379 return Some((
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
380 Cow::Borrowed(normalized),
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
381 INVALID_PATH_DISPATCH,
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
382 ))
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
383 }
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
384 };
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
385 let target = self.root_dir.join(buf);
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
386 let st = target.symlink_metadata();
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
387 let in_dmap = self.dmap.get(normalized);
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
388 match st {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
389 Ok(meta) => {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
390 let file_type = meta.file_type();
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
391 return if file_type.is_file() || file_type.is_symlink()
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
392 {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
393 if let Some(entry) = in_dmap {
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
394 return Some((
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
395 Cow::Borrowed(normalized),
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
396 dispatch_found(
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
397 &normalized,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
398 *entry,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
399 HgMetadata::from_metadata(meta),
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
400 &self.dmap.copy_map,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
401 self.options,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
402 ),
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
403 ));
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
404 }
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
405 Some((
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
406 Cow::Borrowed(normalized),
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
407 Dispatch::Unknown,
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
408 ))
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
409 } else if file_type.is_dir() {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
410 if self.options.collect_traversed_dirs {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
411 traversed_sender
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
412 .send(normalized.to_owned())
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
413 .expect("receiver should outlive sender");
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
414 }
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
415 Some((
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
416 Cow::Borrowed(normalized),
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
417 Dispatch::Directory {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
418 was_file: in_dmap.is_some(),
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
419 },
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
420 ))
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
421 } else {
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
422 Some((
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
423 Cow::Borrowed(normalized),
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
424 Dispatch::Bad(BadMatch::BadType(
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
425 // TODO do more than unknown
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
426 // Support for all `BadType` variant
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
427 // varies greatly between platforms.
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
428 // So far, no tests check the type and
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
429 // this should be good enough for most
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
430 // users.
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
431 BadType::Unknown,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
432 )),
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
433 ))
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
434 };
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
435 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
436 Err(_) => {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
437 if let Some(entry) = in_dmap {
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
438 return Some((
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
439 Cow::Borrowed(normalized),
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
440 dispatch_missing(entry.state),
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
441 ));
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
442 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
443 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
444 };
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
445 None
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
446 })
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
447 .partition(|(_, dispatch)| match dispatch {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
448 Dispatch::Directory { .. } => true,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
449 _ => false,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
450 })
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
451 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
452
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
453 /// Walk the working directory recursively to look for changes compared to
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
454 /// the current `DirstateMap`.
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
455 ///
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
456 /// This takes a mutable reference to the results to account for the
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
457 /// `extend` in timings
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
458 #[timed]
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
459 pub fn traverse(
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
460 &self,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
461 path: impl AsRef<HgPath>,
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
462 old_results: &FastHashMap<HgPathCow<'a>, Dispatch>,
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
463 results: &mut Vec<DispatchedPath<'a>>,
46054
fd47483f1645 rust: use crossbeam-channel crate directly
Simon Sapin <simon-commits@exyr.org>
parents: 45862
diff changeset
464 traversed_sender: crossbeam_channel::Sender<HgPathBuf>,
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
465 ) {
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
466 // The traversal is done in parallel, so use a channel to gather
46054
fd47483f1645 rust: use crossbeam-channel crate directly
Simon Sapin <simon-commits@exyr.org>
parents: 45862
diff changeset
467 // entries. `crossbeam_channel::Sender` is `Sync`, while `mpsc::Sender`
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
468 // is not.
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
469 let (files_transmitter, files_receiver) =
46054
fd47483f1645 rust: use crossbeam-channel crate directly
Simon Sapin <simon-commits@exyr.org>
parents: 45862
diff changeset
470 crossbeam_channel::unbounded();
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
471
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
472 self.traverse_dir(
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
473 &files_transmitter,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
474 path,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
475 &old_results,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
476 traversed_sender,
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
477 );
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
478
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
479 // Disconnect the channel so the receiver stops waiting
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
480 drop(files_transmitter);
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
481
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
482 let new_results = files_receiver
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
483 .into_iter()
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
484 .par_bridge()
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
485 .map(|(f, d)| (Cow::Owned(f), d));
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
486
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
487 results.par_extend(new_results);
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
488 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
489
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
490 /// Dispatch a single entry (file, folder, symlink...) found during
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
491 /// `traverse`. If the entry is a folder that needs to be traversed, it
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
492 /// will be handled in a separate thread.
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
493 fn handle_traversed_entry<'b>(
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
494 &'a self,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
495 scope: &rayon::Scope<'b>,
46054
fd47483f1645 rust: use crossbeam-channel crate directly
Simon Sapin <simon-commits@exyr.org>
parents: 45862
diff changeset
496 files_sender: &'b crossbeam_channel::Sender<(HgPathBuf, Dispatch)>,
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
497 old_results: &'a FastHashMap<Cow<HgPath>, Dispatch>,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
498 filename: HgPathBuf,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
499 dir_entry: DirEntry,
46054
fd47483f1645 rust: use crossbeam-channel crate directly
Simon Sapin <simon-commits@exyr.org>
parents: 45862
diff changeset
500 traversed_sender: crossbeam_channel::Sender<HgPathBuf>,
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
501 ) -> IoResult<()>
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
502 where
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
503 'a: 'b,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
504 {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
505 let file_type = dir_entry.file_type()?;
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
506 let entry_option = self.dmap.get(&filename);
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
507
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
508 if filename.as_bytes() == b".hg" {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
509 // Could be a directory or a symlink
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
510 return Ok(());
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
511 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
512
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
513 if file_type.is_dir() {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
514 self.handle_traversed_dir(
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
515 scope,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
516 files_sender,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
517 old_results,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
518 entry_option,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
519 filename,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
520 traversed_sender,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
521 );
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
522 } else if file_type.is_file() || file_type.is_symlink() {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
523 if let Some(entry) = entry_option {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
524 if self.matcher.matches_everything()
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
525 || self.matcher.matches(&filename)
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
526 {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
527 let metadata = dir_entry.metadata()?;
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
528 files_sender
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
529 .send((
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
530 filename.to_owned(),
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
531 dispatch_found(
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
532 &filename,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
533 *entry,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
534 HgMetadata::from_metadata(metadata),
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
535 &self.dmap.copy_map,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
536 self.options,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
537 ),
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
538 ))
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
539 .unwrap();
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
540 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
541 } else if (self.matcher.matches_everything()
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
542 || self.matcher.matches(&filename))
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
543 && !self.is_ignored(&filename)
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
544 {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
545 if (self.options.list_ignored
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
546 || self.matcher.exact_match(&filename))
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
547 && self.dir_ignore(&filename)
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
548 {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
549 if self.options.list_ignored {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
550 files_sender
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
551 .send((filename.to_owned(), Dispatch::Ignored))
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
552 .unwrap();
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
553 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
554 } else if self.options.list_unknown {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
555 files_sender
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
556 .send((filename.to_owned(), Dispatch::Unknown))
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
557 .unwrap();
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
558 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
559 } else if self.is_ignored(&filename) && self.options.list_ignored {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
560 files_sender
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
561 .send((filename.to_owned(), Dispatch::Ignored))
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
562 .unwrap();
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
563 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
564 } else if let Some(entry) = entry_option {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
565 // Used to be a file or a folder, now something else.
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
566 if self.matcher.matches_everything()
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
567 || self.matcher.matches(&filename)
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
568 {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
569 files_sender
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
570 .send((filename.to_owned(), dispatch_missing(entry.state)))
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
571 .unwrap();
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
572 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
573 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
574
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
575 Ok(())
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
576 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
577
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
578 /// A directory was found in the filesystem and needs to be traversed
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
579 fn handle_traversed_dir<'b>(
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
580 &'a self,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
581 scope: &rayon::Scope<'b>,
46054
fd47483f1645 rust: use crossbeam-channel crate directly
Simon Sapin <simon-commits@exyr.org>
parents: 45862
diff changeset
582 files_sender: &'b crossbeam_channel::Sender<(HgPathBuf, Dispatch)>,
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
583 old_results: &'a FastHashMap<Cow<HgPath>, Dispatch>,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
584 entry_option: Option<&'a DirstateEntry>,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
585 directory: HgPathBuf,
46054
fd47483f1645 rust: use crossbeam-channel crate directly
Simon Sapin <simon-commits@exyr.org>
parents: 45862
diff changeset
586 traversed_sender: crossbeam_channel::Sender<HgPathBuf>,
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
587 ) where
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
588 'a: 'b,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
589 {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
590 scope.spawn(move |_| {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
591 // Nested `if` until `rust-lang/rust#53668` is stable
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
592 if let Some(entry) = entry_option {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
593 // Used to be a file, is now a folder
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
594 if self.matcher.matches_everything()
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
595 || self.matcher.matches(&directory)
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
596 {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
597 files_sender
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
598 .send((
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
599 directory.to_owned(),
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
600 dispatch_missing(entry.state),
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
601 ))
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
602 .unwrap();
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
603 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
604 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
605 // Do we need to traverse it?
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
606 if !self.is_ignored(&directory) || self.options.list_ignored {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
607 self.traverse_dir(
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
608 files_sender,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
609 directory,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
610 &old_results,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
611 traversed_sender,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
612 )
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
613 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
614 });
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
615 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
616
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
617 /// Decides whether the directory needs to be listed, and if so handles the
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
618 /// entries in a separate thread.
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
619 fn traverse_dir(
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
620 &self,
46054
fd47483f1645 rust: use crossbeam-channel crate directly
Simon Sapin <simon-commits@exyr.org>
parents: 45862
diff changeset
621 files_sender: &crossbeam_channel::Sender<(HgPathBuf, Dispatch)>,
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
622 directory: impl AsRef<HgPath>,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
623 old_results: &FastHashMap<Cow<HgPath>, Dispatch>,
46054
fd47483f1645 rust: use crossbeam-channel crate directly
Simon Sapin <simon-commits@exyr.org>
parents: 45862
diff changeset
624 traversed_sender: crossbeam_channel::Sender<HgPathBuf>,
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
625 ) {
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
626 let directory = directory.as_ref();
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
627
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
628 if self.options.collect_traversed_dirs {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
629 traversed_sender
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
630 .send(directory.to_owned())
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
631 .expect("receiver should outlive sender");
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
632 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
633
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
634 let visit_entries = match self.matcher.visit_children_set(directory) {
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
635 VisitChildrenSet::Empty => return,
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
636 VisitChildrenSet::This | VisitChildrenSet::Recursive => None,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
637 VisitChildrenSet::Set(set) => Some(set),
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
638 };
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
639 let buf = match hg_path_to_path_buf(directory) {
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
640 Ok(b) => b,
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
641 Err(_) => {
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
642 files_sender
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
643 .send((directory.to_owned(), INVALID_PATH_DISPATCH))
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
644 .expect("receiver should outlive sender");
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
645 return;
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
646 }
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
647 };
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
648 let dir_path = self.root_dir.join(buf);
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
649
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
650 let skip_dot_hg = !directory.as_bytes().is_empty();
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
651 let entries = match list_directory(dir_path, skip_dot_hg) {
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
652 Err(e) => {
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
653 files_sender
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
654 .send((directory.to_owned(), dispatch_os_error(&e)))
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
655 .expect("receiver should outlive sender");
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
656 return;
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
657 }
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
658 Ok(entries) => entries,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
659 };
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
660
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
661 rayon::scope(|scope| {
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
662 for (filename, dir_entry) in entries {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
663 if let Some(ref set) = visit_entries {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
664 if !set.contains(filename.deref()) {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
665 continue;
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
666 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
667 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
668 // TODO normalize
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
669 let filename = if directory.is_empty() {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
670 filename.to_owned()
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
671 } else {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
672 directory.join(&filename)
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
673 };
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
674
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
675 if !old_results.contains_key(filename.deref()) {
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
676 match self.handle_traversed_entry(
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
677 scope,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
678 files_sender,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
679 old_results,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
680 filename,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
681 dir_entry,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
682 traversed_sender.clone(),
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
683 ) {
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
684 Err(e) => {
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
685 files_sender
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
686 .send((
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
687 directory.to_owned(),
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
688 dispatch_os_error(&e),
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
689 ))
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
690 .expect("receiver should outlive sender");
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
691 }
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
692 Ok(_) => {}
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
693 }
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
694 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
695 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
696 })
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
697 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
698
45610
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
699 /// Add the files in the dirstate to the results.
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
700 ///
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
701 /// This takes a mutable reference to the results to account for the
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
702 /// `extend` in timings
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
703 #[timed]
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
704 pub fn extend_from_dmap(&self, results: &mut Vec<DispatchedPath<'a>>) {
46489
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
705 results.par_extend(
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
706 self.dmap
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
707 .par_iter()
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
708 .filter(|(path, _)| self.matcher.matches(path))
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
709 .map(move |(filename, entry)| {
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
710 let filename: &HgPath = filename;
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
711 let filename_as_path = match hg_path_to_path_buf(filename)
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
712 {
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
713 Ok(f) => f,
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
714 Err(_) => {
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
715 return (
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
716 Cow::Borrowed(filename),
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
717 INVALID_PATH_DISPATCH,
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
718 )
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
719 }
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
720 };
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
721 let meta = self
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
722 .root_dir
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
723 .join(filename_as_path)
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
724 .symlink_metadata();
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
725 match meta {
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
726 Ok(m)
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
727 if !(m.file_type().is_file()
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
728 || m.file_type().is_symlink()) =>
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
729 {
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
730 (
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
731 Cow::Borrowed(filename),
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
732 dispatch_missing(entry.state),
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
733 )
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
734 }
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
735 Ok(m) => (
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
736 Cow::Borrowed(filename),
46489
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
737 dispatch_found(
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
738 filename,
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
739 *entry,
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
740 HgMetadata::from_metadata(m),
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
741 &self.dmap.copy_map,
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
742 self.options,
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
743 ),
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
744 ),
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
745 Err(e)
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
746 if e.kind() == ErrorKind::NotFound
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
747 || e.raw_os_error() == Some(20) =>
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
748 {
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
749 // Rust does not yet have an `ErrorKind` for
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
750 // `NotADirectory` (errno 20)
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
751 // It happens if the dirstate contains `foo/bar`
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
752 // and foo is not a
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
753 // directory
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
754 (
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
755 Cow::Borrowed(filename),
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
756 dispatch_missing(entry.state),
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
757 )
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
758 }
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
759 Err(e) => {
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
760 (Cow::Borrowed(filename), dispatch_os_error(&e))
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
761 }
45610
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
762 }
46489
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
763 }),
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
764 );
45610
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
765 }
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
766
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
767 /// Checks all files that are in the dirstate but were not found during the
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
768 /// working directory traversal. This means that the rest must
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
769 /// be either ignored, under a symlink or under a new nested repo.
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
770 ///
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
771 /// This takes a mutable reference to the results to account for the
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
772 /// `extend` in timings
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
773 #[timed]
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
774 pub fn handle_unknowns(&self, results: &mut Vec<DispatchedPath<'a>>) {
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
775 let to_visit: Vec<(&HgPath, &DirstateEntry)> =
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
776 if results.is_empty() && self.matcher.matches_everything() {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
777 self.dmap.iter().map(|(f, e)| (f.deref(), e)).collect()
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
778 } else {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
779 // Only convert to a hashmap if needed.
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
780 let old_results: FastHashMap<_, _> =
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
781 results.iter().cloned().collect();
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
782 self.dmap
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
783 .iter()
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
784 .filter_map(move |(f, e)| {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
785 if !old_results.contains_key(f.deref())
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
786 && self.matcher.matches(f)
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
787 {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
788 Some((f.deref(), e))
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
789 } else {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
790 None
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
791 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
792 })
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
793 .collect()
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
794 };
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
795
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
796 let path_auditor = PathAuditor::new(&self.root_dir);
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
797
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
798 let new_results = to_visit.into_par_iter().filter_map(
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
799 |(filename, entry)| -> Option<_> {
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
800 // Report ignored items in the dmap as long as they are not
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
801 // under a symlink directory.
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
802 if path_auditor.check(filename) {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
803 // TODO normalize for case-insensitive filesystems
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
804 let buf = match hg_path_to_path_buf(filename) {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
805 Ok(x) => x,
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
806 Err(_) => {
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
807 return Some((
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
808 Cow::Owned(filename.to_owned()),
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
809 INVALID_PATH_DISPATCH,
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
810 ));
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
811 }
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
812 };
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
813 Some((
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
814 Cow::Owned(filename.to_owned()),
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
815 match self.root_dir.join(&buf).symlink_metadata() {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
816 // File was just ignored, no links, and exists
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
817 Ok(meta) => {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
818 let metadata = HgMetadata::from_metadata(meta);
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
819 dispatch_found(
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
820 filename,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
821 *entry,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
822 metadata,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
823 &self.dmap.copy_map,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
824 self.options,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
825 )
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
826 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
827 // File doesn't exist
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
828 Err(_) => dispatch_missing(entry.state),
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
829 },
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
830 ))
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
831 } else {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
832 // It's either missing or under a symlink directory which
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
833 // we, in this case, report as missing.
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
834 Some((
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
835 Cow::Owned(filename.to_owned()),
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
836 dispatch_missing(entry.state),
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
837 ))
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
838 }
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
839 },
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
840 );
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
841
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
842 results.par_extend(new_results);
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
843 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
844 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
845
44541
d880805d5442 hg-core: add function timing information
Raphaël Gomès <rgomes@octobus.net>
parents: 44539
diff changeset
846 #[timed]
45113
98817e5daca7 hg-core: define a `dirstate_status` `Operation`
Raphaël Gomès <rgomes@octobus.net>
parents: 45112
diff changeset
847 pub fn build_response<'a>(
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
848 results: impl IntoIterator<Item = DispatchedPath<'a>>,
44838
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
849 traversed: Vec<HgPathBuf>,
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
850 ) -> (Vec<HgPathCow<'a>>, DirstateStatus<'a>) {
43271
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
851 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
852 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
853 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
854 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
855 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
856 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
857 let mut ignored = vec![];
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
858 let mut unknown = vec![];
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
859 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
860
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
861 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
862 match dispatch {
44526
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
863 Dispatch::Unknown => unknown.push(filename),
43602
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
864 Dispatch::Unsure => lookup.push(filename),
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
865 Dispatch::Modified => modified.push(filename),
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
866 Dispatch::Added => added.push(filename),
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
867 Dispatch::Removed => removed.push(filename),
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
868 Dispatch::Deleted => deleted.push(filename),
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
869 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
870 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
871 Dispatch::None => {}
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
872 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
873 Dispatch::Directory { .. } => {}
43271
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
874 }
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
875 }
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
876
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
877 (
43271
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
878 lookup,
44525
f13d19549efd rust-status: rename `StatusResult` to `DirstateStatus`
Raphaël Gomès <rgomes@octobus.net>
parents: 44524
diff changeset
879 DirstateStatus {
43271
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
880 modified,
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
881 added,
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
882 removed,
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
883 deleted,
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
884 clean,
44526
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
885 ignored,
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
886 unknown,
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
887 bad,
44838
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
888 traversed,
43271
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
889 },
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
890 )
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
891 }
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
892
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
893 /// 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
894 ///
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
895 /// 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
896 /// 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
897 /// 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
898 #[timed]
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
899 pub fn status<'a>(
43915
8c77826116f7 rust-dirstate-status: add `walk_explicit` implementation, use `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43818
diff changeset
900 dmap: &'a DirstateMap,
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
901 matcher: &'a (impl Matcher + Sync),
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
902 root_dir: PathBuf,
44597
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
903 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
904 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
905 ) -> StatusResult<(
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
906 (Vec<HgPathCow<'a>>, 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
907 Vec<PatternFileWarning>,
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
908 )> {
45113
98817e5daca7 hg-core: define a `dirstate_status` `Operation`
Raphaël Gomès <rgomes@octobus.net>
parents: 45112
diff changeset
909 let (status, warnings) =
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
910 Status::new(dmap, matcher, root_dir, ignore_files, options)?;
44838
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
911
45113
98817e5daca7 hg-core: define a `dirstate_status` `Operation`
Raphaël Gomès <rgomes@octobus.net>
parents: 45112
diff changeset
912 Ok((status.run()?, warnings))
43271
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
913 }