annotate rust/hg-core/src/dirstate/status.rs @ 52307:22d24f6d6411

rust-lib: remove exports for not too common pattern-related types This only muddies the lib and makes the imports more confusing.
author Raphaël Gomès <rgomes@octobus.net>
date Mon, 04 Nov 2024 11:26:41 +0100
parents f33b87b46135
children
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
52302
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
12 use crate::dirstate::dirstate_map::BorrowedPath;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
13 use crate::dirstate::dirstate_map::ChildNodesRef;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
14 use crate::dirstate::dirstate_map::DirstateMap;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
15 use crate::dirstate::dirstate_map::DirstateVersion;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
16 use crate::dirstate::dirstate_map::NodeRef;
48501
4afb9627dc77 dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents: 48454
diff changeset
17 use crate::dirstate::entry::TruncatedTimestamp;
52302
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
18 use crate::dirstate::on_disk::DirstateV2ParseError;
52306
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Raphaël Gomès <rgomes@octobus.net>
parents: 52302
diff changeset
19 use crate::filepatterns::PatternError;
52307
22d24f6d6411 rust-lib: remove exports for not too common pattern-related types
Raphaël Gomès <rgomes@octobus.net>
parents: 52306
diff changeset
20 use crate::filepatterns::PatternFileWarning;
52302
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
21 use crate::matchers::get_ignore_function;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
22 use crate::matchers::{Matcher, VisitChildrenSet};
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
23 use crate::utils::files::filesystem_now;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
24 use crate::utils::files::get_bytes_from_os_string;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
25 use crate::utils::files::get_bytes_from_path;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
26 use crate::utils::files::get_path_from_bytes;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
27 use crate::utils::hg_path::hg_path_to_path_buf;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
28 use crate::utils::hg_path::HgPath;
52306
f33b87b46135 rust-lib: move `PatternError` to the `filepatterns` module
Raphaël Gomès <rgomes@octobus.net>
parents: 52302
diff changeset
29 use crate::utils::hg_path::HgPathError;
52302
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
30 use once_cell::sync::OnceCell;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
31 use rayon::prelude::*;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
32 use sha1::{Digest, Sha1};
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
33 use std::io;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
34 use std::os::unix::prelude::FileTypeExt;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
35 use std::path::Path;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
36 use std::path::PathBuf;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
37 use std::sync::Mutex;
48068
bf8837e3d7ce dirstate: Remove the flat Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents: 48026
diff changeset
38
bf8837e3d7ce dirstate: Remove the flat Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents: 48026
diff changeset
39 use std::{borrow::Cow, fmt};
43271
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
40
44526
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
41 /// 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
42 /// Note: a lot of those don't exist on all platforms.
50862
5efccea9cf38 rust-status: explicitly track bad file types
Spencer Baugh <sbaugh@janestreet.com>
parents: 49000
diff changeset
43 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
44526
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
44 pub enum BadType {
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
45 CharacterDevice,
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
46 BlockDevice,
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
47 FIFO,
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
48 Socket,
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
49 Directory,
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
50 Unknown,
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
51 }
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
52
46444
6c778d20c8c2 rust: replace ToString impls with Display
Simon Sapin <simon.sapin@octobus.net>
parents: 46435
diff changeset
53 impl fmt::Display for BadType {
6c778d20c8c2 rust: replace ToString impls with Display
Simon Sapin <simon.sapin@octobus.net>
parents: 46435
diff changeset
54 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
55 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
56 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
57 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
58 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
59 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
60 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
61 BadType::Unknown => "unknown",
46444
6c778d20c8c2 rust: replace ToString impls with Display
Simon Sapin <simon.sapin@octobus.net>
parents: 46435
diff changeset
62 })
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
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 }
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
65
44526
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
66 /// 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
67 #[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
68 pub enum BadMatch {
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
69 OsError(i32),
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
70 BadType(BadType),
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
71 }
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
72
47113
be579775c2d9 dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents: 47112
diff changeset
73 /// `Box<dyn Trait>` is syntactic sugar for `Box<dyn Trait + 'static>`, so add
44597
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
74 /// an explicit lifetime here to not fight `'static` bounds "out of nowhere".
47112
d5956136d19d dirstate-tree: Give to `status()` mutable access to the `DirstateMap`
Simon Sapin <simon.sapin@octobus.net>
parents: 47111
diff changeset
75 pub type IgnoreFnType<'a> =
d5956136d19d dirstate-tree: Give to `status()` mutable access to the `DirstateMap`
Simon Sapin <simon.sapin@octobus.net>
parents: 47111
diff changeset
76 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
77
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
78 /// 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
79 /// 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
80 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
81
44524
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
82 #[derive(Debug, Copy, Clone)]
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
83 pub struct StatusOptions {
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
84 /// 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
85 pub check_exec: bool,
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
86 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
87 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
88 pub list_ignored: bool,
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48422
diff changeset
89 /// Whether to populate `StatusPath::copy_source`
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48422
diff changeset
90 pub list_copies: bool,
44838
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
91 /// 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
92 /// 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
93 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
94 }
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
95
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48422
diff changeset
96 #[derive(Default)]
44525
f13d19549efd rust-status: rename `StatusResult` to `DirstateStatus`
Raphaël Gomès <rgomes@octobus.net>
parents: 44524
diff changeset
97 pub struct DirstateStatus<'a> {
48422
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48391
diff changeset
98 /// The current time at the start of the `status()` algorithm, as measured
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48391
diff changeset
99 /// and possibly truncated by the filesystem.
48501
4afb9627dc77 dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents: 48454
diff changeset
100 pub filesystem_time_at_status_start: Option<TruncatedTimestamp>,
48422
000130cfafb6 rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents: 48391
diff changeset
101
47111
623c8e4ddc6d rust: Add doc-comments to DirstateStatus fields
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
102 /// Tracked files whose contents have changed since the parent revision
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48422
diff changeset
103 pub modified: Vec<StatusPath<'a>>,
47111
623c8e4ddc6d rust: Add doc-comments to DirstateStatus fields
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
104
623c8e4ddc6d rust: Add doc-comments to DirstateStatus fields
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
105 /// Newly-tracked files that were not present in the parent
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48422
diff changeset
106 pub added: Vec<StatusPath<'a>>,
47111
623c8e4ddc6d rust: Add doc-comments to DirstateStatus fields
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
107
623c8e4ddc6d rust: Add doc-comments to DirstateStatus fields
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
108 /// Previously-tracked files that have been (re)moved with an hg command
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48422
diff changeset
109 pub removed: Vec<StatusPath<'a>>,
47111
623c8e4ddc6d rust: Add doc-comments to DirstateStatus fields
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
110
623c8e4ddc6d rust: Add doc-comments to DirstateStatus fields
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
111 /// (Still) tracked files that are missing, (re)moved with an non-hg
623c8e4ddc6d rust: Add doc-comments to DirstateStatus fields
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
112 /// command
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48422
diff changeset
113 pub deleted: Vec<StatusPath<'a>>,
47111
623c8e4ddc6d rust: Add doc-comments to DirstateStatus fields
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
114
623c8e4ddc6d rust: Add doc-comments to DirstateStatus fields
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
115 /// Tracked files that are up to date with the parent.
623c8e4ddc6d rust: Add doc-comments to DirstateStatus fields
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
116 /// Only pupulated if `StatusOptions::list_clean` is true.
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48422
diff changeset
117 pub clean: Vec<StatusPath<'a>>,
47111
623c8e4ddc6d rust: Add doc-comments to DirstateStatus fields
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
118
623c8e4ddc6d rust: Add doc-comments to DirstateStatus fields
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
119 /// Files in the working directory that are ignored with `.hgignore`.
623c8e4ddc6d rust: Add doc-comments to DirstateStatus fields
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
120 /// Only pupulated if `StatusOptions::list_ignored` is true.
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48422
diff changeset
121 pub ignored: Vec<StatusPath<'a>>,
47111
623c8e4ddc6d rust: Add doc-comments to DirstateStatus fields
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
122
623c8e4ddc6d rust: Add doc-comments to DirstateStatus fields
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
123 /// Files in the working directory that are neither tracked nor ignored.
623c8e4ddc6d rust: Add doc-comments to DirstateStatus fields
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
124 /// Only pupulated if `StatusOptions::list_unknown` is true.
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48422
diff changeset
125 pub unknown: Vec<StatusPath<'a>>,
47111
623c8e4ddc6d rust: Add doc-comments to DirstateStatus fields
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
126
623c8e4ddc6d rust: Add doc-comments to DirstateStatus fields
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
127 /// Was explicitly matched but cannot be found/accessed
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
128 pub bad: Vec<(HgPathCow<'a>, BadMatch)>,
47111
623c8e4ddc6d rust: Add doc-comments to DirstateStatus fields
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
129
47110
9c6b458a08e1 rust: Move "lookup" a.k.a. "unsure" paths into `DirstateStatus` struct
Simon Sapin <simon.sapin@octobus.net>
parents: 47093
diff changeset
130 /// Either clean or modified, but we can’t tell from filesystem metadata
9c6b458a08e1 rust: Move "lookup" a.k.a. "unsure" paths into `DirstateStatus` struct
Simon Sapin <simon.sapin@octobus.net>
parents: 47093
diff changeset
131 /// alone. The file contents need to be read and compared with that in
9c6b458a08e1 rust: Move "lookup" a.k.a. "unsure" paths into `DirstateStatus` struct
Simon Sapin <simon.sapin@octobus.net>
parents: 47093
diff changeset
132 /// the parent.
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48422
diff changeset
133 pub unsure: Vec<StatusPath<'a>>,
47111
623c8e4ddc6d rust: Add doc-comments to DirstateStatus fields
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
134
44838
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
135 /// Only filled if `collect_traversed_dirs` is `true`
47347
73ddcedeaadf dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents: 47335
diff changeset
136 pub traversed: Vec<HgPathCow<'a>>,
47350
04d1f17f49e7 dirstate-v2: Write .hg/dirstate back to disk on directory cache changes
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
137
04d1f17f49e7 dirstate-v2: Write .hg/dirstate back to disk on directory cache changes
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
138 /// Whether `status()` made changed to the `DirstateMap` that should be
04d1f17f49e7 dirstate-v2: Write .hg/dirstate back to disk on directory cache changes
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
139 /// written back to disk
04d1f17f49e7 dirstate-v2: Write .hg/dirstate back to disk on directory cache changes
Simon Sapin <simon.sapin@octobus.net>
parents: 47347
diff changeset
140 pub dirty: bool,
43271
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
141 }
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
142
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48422
diff changeset
143 #[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48422
diff changeset
144 pub struct StatusPath<'a> {
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48422
diff changeset
145 pub path: HgPathCow<'a>,
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48422
diff changeset
146 pub copy_source: Option<HgPathCow<'a>>,
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48422
diff changeset
147 }
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48422
diff changeset
148
46435
2e2033081274 rust: replace trivial `impl From …` with `#[derive(derive_more::From)]`
Simon Sapin <simon.sapin@octobus.net>
parents: 46054
diff changeset
149 #[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
150 pub enum StatusError {
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
151 /// 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
152 Path(HgPathError),
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
153 /// 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
154 Pattern(PatternError),
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47329
diff changeset
155 /// Corrupted dirstate
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47329
diff changeset
156 DirstateV2ParseError(DirstateV2ParseError),
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
157 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
158
46444
6c778d20c8c2 rust: replace ToString impls with Display
Simon Sapin <simon.sapin@octobus.net>
parents: 46435
diff changeset
159 impl fmt::Display for StatusError {
6c778d20c8c2 rust: replace ToString impls with Display
Simon Sapin <simon.sapin@octobus.net>
parents: 46435
diff changeset
160 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
161 match self {
46444
6c778d20c8c2 rust: replace ToString impls with Display
Simon Sapin <simon.sapin@octobus.net>
parents: 46435
diff changeset
162 StatusError::Path(error) => error.fmt(f),
6c778d20c8c2 rust: replace ToString impls with Display
Simon Sapin <simon.sapin@octobus.net>
parents: 46435
diff changeset
163 StatusError::Pattern(error) => error.fmt(f),
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47329
diff changeset
164 StatusError::DirstateV2ParseError(_) => {
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47329
diff changeset
165 f.write_str("dirstate-v2 parse error")
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47329
diff changeset
166 }
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
167 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
168 }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
169 }
52302
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
170
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
171 /// Returns the status of the working directory compared to its parent
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
172 /// changeset.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
173 ///
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
174 /// This algorithm is based on traversing the filesystem tree (`fs` in function
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
175 /// and variable names) and dirstate tree at the same time. The core of this
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
176 /// traversal is the recursive `traverse_fs_directory_and_dirstate` function
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
177 /// and its use of `itertools::merge_join_by`. When reaching a path that only
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
178 /// exists in one of the two trees, depending on information requested by
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
179 /// `options` we may need to traverse the remaining subtree.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
180 #[logging_timer::time("trace")]
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
181 pub fn status<'dirstate>(
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
182 dmap: &'dirstate mut DirstateMap,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
183 matcher: &(dyn Matcher + Sync),
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
184 root_dir: PathBuf,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
185 ignore_files: Vec<PathBuf>,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
186 options: StatusOptions,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
187 ) -> Result<(DirstateStatus<'dirstate>, Vec<PatternFileWarning>), StatusError>
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
188 {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
189 // Also cap for a Python caller of this function, but don't complain if
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
190 // the global threadpool has already been set since this code path is also
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
191 // being used by `rhg`, which calls this early.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
192 let _ = crate::utils::cap_default_rayon_threads();
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
193
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
194 let (ignore_fn, warnings, patterns_changed): (IgnoreFnType, _, _) =
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
195 if options.list_ignored || options.list_unknown {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
196 let (ignore_fn, warnings, changed) = match dmap.dirstate_version {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
197 DirstateVersion::V1 => {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
198 let (ignore_fn, warnings) = get_ignore_function(
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
199 ignore_files,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
200 &root_dir,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
201 &mut |_source, _pattern_bytes| {},
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
202 )?;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
203 (ignore_fn, warnings, None)
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
204 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
205 DirstateVersion::V2 => {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
206 let mut hasher = Sha1::new();
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
207 let (ignore_fn, warnings) = get_ignore_function(
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
208 ignore_files,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
209 &root_dir,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
210 &mut |source, pattern_bytes| {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
211 // If inside the repo, use the relative version to
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
212 // make it deterministic inside tests.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
213 // The performance hit should be negligible.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
214 let source = source
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
215 .strip_prefix(&root_dir)
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
216 .unwrap_or(source);
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
217 let source = get_bytes_from_path(source);
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
218
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
219 let mut subhasher = Sha1::new();
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
220 subhasher.update(pattern_bytes);
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
221 let patterns_hash = subhasher.finalize();
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
222
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
223 hasher.update(source);
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
224 hasher.update(b" ");
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
225 hasher.update(patterns_hash);
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
226 hasher.update(b"\n");
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
227 },
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
228 )?;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
229 let new_hash = *hasher.finalize().as_ref();
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
230 let changed = new_hash != dmap.ignore_patterns_hash;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
231 dmap.ignore_patterns_hash = new_hash;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
232 (ignore_fn, warnings, Some(changed))
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
233 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
234 };
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
235 (ignore_fn, warnings, changed)
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
236 } else {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
237 (Box::new(|&_| true), vec![], None)
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
238 };
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
239
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
240 let filesystem_time_at_status_start =
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
241 filesystem_now(&root_dir).ok().map(TruncatedTimestamp::from);
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
242
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
243 // If the repository is under the current directory, prefer using a
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
244 // relative path, so the kernel needs to traverse fewer directory in every
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
245 // call to `read_dir` or `symlink_metadata`.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
246 // This is effective in the common case where the current directory is the
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
247 // repository root.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
248
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
249 // TODO: Better yet would be to use libc functions like `openat` and
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
250 // `fstatat` to remove such repeated traversals entirely, but the standard
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
251 // library does not provide APIs based on those.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
252 // Maybe with a crate like https://crates.io/crates/openat instead?
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
253 let root_dir = if let Some(relative) = std::env::current_dir()
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
254 .ok()
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
255 .and_then(|cwd| root_dir.strip_prefix(cwd).ok())
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
256 {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
257 relative
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
258 } else {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
259 &root_dir
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
260 };
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
261
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
262 let outcome = DirstateStatus {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
263 filesystem_time_at_status_start,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
264 ..Default::default()
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
265 };
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
266 let common = StatusCommon {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
267 dmap,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
268 options,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
269 matcher,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
270 ignore_fn,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
271 outcome: Mutex::new(outcome),
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
272 ignore_patterns_have_changed: patterns_changed,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
273 new_cacheable_directories: Default::default(),
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
274 outdated_cached_directories: Default::default(),
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
275 filesystem_time_at_status_start,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
276 };
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
277 let is_at_repo_root = true;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
278 let hg_path = &BorrowedPath::OnDisk(HgPath::new(""));
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
279 let has_ignored_ancestor = HasIgnoredAncestor::create(None, hg_path);
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
280 let root_cached_mtime = None;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
281 // If the path we have for the repository root is a symlink, do follow it.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
282 // (As opposed to symlinks within the working directory which are not
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
283 // followed, using `std::fs::symlink_metadata`.)
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
284 common.traverse_fs_directory_and_dirstate(
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
285 &has_ignored_ancestor,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
286 dmap.root.as_ref(),
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
287 hg_path,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
288 &DirEntry {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
289 hg_path: Cow::Borrowed(HgPath::new(b"")),
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
290 fs_path: Cow::Borrowed(root_dir),
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
291 symlink_metadata: None,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
292 file_type: FakeFileType::Directory,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
293 },
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
294 root_cached_mtime,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
295 is_at_repo_root,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
296 )?;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
297 if let Some(file_set) = common.matcher.file_set() {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
298 for file in file_set {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
299 if !file.is_empty() && !dmap.has_node(file)? {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
300 let path = hg_path_to_path_buf(file)?;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
301 if let io::Result::Err(error) =
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
302 root_dir.join(path).symlink_metadata()
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
303 {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
304 common.io_error(error, file)
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
305 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
306 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
307 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
308 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
309 let mut outcome = common.outcome.into_inner().unwrap();
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
310 let new_cacheable = common.new_cacheable_directories.into_inner().unwrap();
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
311 let outdated = common.outdated_cached_directories.into_inner().unwrap();
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
312
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
313 outcome.dirty = common.ignore_patterns_have_changed == Some(true)
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
314 || !outdated.is_empty()
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
315 || (!new_cacheable.is_empty()
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
316 && dmap.dirstate_version == DirstateVersion::V2);
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
317
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
318 // Remove outdated mtimes before adding new mtimes, in case a given
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
319 // directory is both
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
320 for path in &outdated {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
321 dmap.clear_cached_mtime(path)?;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
322 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
323 for (path, mtime) in &new_cacheable {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
324 dmap.set_cached_mtime(path, *mtime)?;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
325 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
326
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
327 Ok((outcome, warnings))
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
328 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
329
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
330 /// Bag of random things needed by various parts of the algorithm. Reduces the
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
331 /// number of parameters passed to functions.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
332 struct StatusCommon<'a, 'tree, 'on_disk: 'tree> {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
333 dmap: &'tree DirstateMap<'on_disk>,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
334 options: StatusOptions,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
335 matcher: &'a (dyn Matcher + Sync),
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
336 ignore_fn: IgnoreFnType<'a>,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
337 outcome: Mutex<DirstateStatus<'on_disk>>,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
338 /// New timestamps of directories to be used for caching their readdirs
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
339 new_cacheable_directories:
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
340 Mutex<Vec<(Cow<'on_disk, HgPath>, TruncatedTimestamp)>>,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
341 /// Used to invalidate the readdir cache of directories
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
342 outdated_cached_directories: Mutex<Vec<Cow<'on_disk, HgPath>>>,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
343
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
344 /// Whether ignore files like `.hgignore` have changed since the previous
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
345 /// time a `status()` call wrote their hash to the dirstate. `None` means
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
346 /// we don’t know as this run doesn’t list either ignored or uknown files
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
347 /// and therefore isn’t reading `.hgignore`.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
348 ignore_patterns_have_changed: Option<bool>,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
349
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
350 /// The current time at the start of the `status()` algorithm, as measured
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
351 /// and possibly truncated by the filesystem.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
352 filesystem_time_at_status_start: Option<TruncatedTimestamp>,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
353 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
354
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
355 enum Outcome {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
356 Modified,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
357 Added,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
358 Removed,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
359 Deleted,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
360 Clean,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
361 Ignored,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
362 Unknown,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
363 Unsure,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
364 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
365
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
366 /// Lazy computation of whether a given path has a hgignored
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
367 /// ancestor.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
368 struct HasIgnoredAncestor<'a> {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
369 /// `path` and `parent` constitute the inputs to the computation,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
370 /// `cache` stores the outcome.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
371 path: &'a HgPath,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
372 parent: Option<&'a HasIgnoredAncestor<'a>>,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
373 cache: OnceCell<bool>,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
374 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
375
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
376 impl<'a> HasIgnoredAncestor<'a> {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
377 fn create(
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
378 parent: Option<&'a HasIgnoredAncestor<'a>>,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
379 path: &'a HgPath,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
380 ) -> HasIgnoredAncestor<'a> {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
381 Self {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
382 path,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
383 parent,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
384 cache: OnceCell::new(),
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
385 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
386 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
387
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
388 fn force(&self, ignore_fn: &IgnoreFnType<'_>) -> bool {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
389 match self.parent {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
390 None => false,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
391 Some(parent) => {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
392 *(self.cache.get_or_init(|| {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
393 parent.force(ignore_fn) || ignore_fn(self.path)
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
394 }))
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
395 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
396 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
397 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
398 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
399
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
400 impl<'a, 'tree, 'on_disk> StatusCommon<'a, 'tree, 'on_disk> {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
401 fn push_outcome(
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
402 &self,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
403 which: Outcome,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
404 dirstate_node: &NodeRef<'tree, 'on_disk>,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
405 ) -> Result<(), DirstateV2ParseError> {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
406 let path = dirstate_node
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
407 .full_path_borrowed(self.dmap.on_disk)?
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
408 .detach_from_tree();
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
409 let copy_source = if self.options.list_copies {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
410 dirstate_node
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
411 .copy_source_borrowed(self.dmap.on_disk)?
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
412 .map(|source| source.detach_from_tree())
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
413 } else {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
414 None
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
415 };
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
416 self.push_outcome_common(which, path, copy_source);
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
417 Ok(())
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
418 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
419
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
420 fn push_outcome_without_copy_source(
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
421 &self,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
422 which: Outcome,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
423 path: &BorrowedPath<'_, 'on_disk>,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
424 ) {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
425 self.push_outcome_common(which, path.detach_from_tree(), None)
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
426 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
427
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
428 fn push_outcome_common(
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
429 &self,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
430 which: Outcome,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
431 path: HgPathCow<'on_disk>,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
432 copy_source: Option<HgPathCow<'on_disk>>,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
433 ) {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
434 let mut outcome = self.outcome.lock().unwrap();
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
435 let vec = match which {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
436 Outcome::Modified => &mut outcome.modified,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
437 Outcome::Added => &mut outcome.added,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
438 Outcome::Removed => &mut outcome.removed,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
439 Outcome::Deleted => &mut outcome.deleted,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
440 Outcome::Clean => &mut outcome.clean,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
441 Outcome::Ignored => &mut outcome.ignored,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
442 Outcome::Unknown => &mut outcome.unknown,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
443 Outcome::Unsure => &mut outcome.unsure,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
444 };
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
445 vec.push(StatusPath { path, copy_source });
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
446 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
447
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
448 fn read_dir(
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
449 &self,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
450 hg_path: &HgPath,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
451 fs_path: &Path,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
452 is_at_repo_root: bool,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
453 ) -> Result<Vec<DirEntry>, ()> {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
454 DirEntry::read_dir(fs_path, is_at_repo_root)
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
455 .map_err(|error| self.io_error(error, hg_path))
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
456 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
457
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
458 fn io_error(&self, error: std::io::Error, hg_path: &HgPath) {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
459 let errno = error.raw_os_error().expect("expected real OS error");
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
460 self.outcome
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
461 .lock()
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
462 .unwrap()
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
463 .bad
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
464 .push((hg_path.to_owned().into(), BadMatch::OsError(errno)))
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
465 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
466
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
467 fn check_for_outdated_directory_cache(
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
468 &self,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
469 dirstate_node: &NodeRef<'tree, 'on_disk>,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
470 ) -> Result<bool, DirstateV2ParseError> {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
471 if self.ignore_patterns_have_changed == Some(true)
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
472 && dirstate_node.cached_directory_mtime()?.is_some()
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
473 {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
474 self.outdated_cached_directories.lock().unwrap().push(
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
475 dirstate_node
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
476 .full_path_borrowed(self.dmap.on_disk)?
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
477 .detach_from_tree(),
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
478 );
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
479 return Ok(true);
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
480 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
481 Ok(false)
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
482 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
483
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
484 /// If this returns true, we can get accurate results by only using
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
485 /// `symlink_metadata` for child nodes that exist in the dirstate and don’t
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
486 /// need to call `read_dir`.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
487 fn can_skip_fs_readdir(
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
488 &self,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
489 directory_entry: &DirEntry,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
490 cached_directory_mtime: Option<TruncatedTimestamp>,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
491 ) -> bool {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
492 if !self.options.list_unknown && !self.options.list_ignored {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
493 // All states that we care about listing have corresponding
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
494 // dirstate entries.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
495 // This happens for example with `hg status -mard`.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
496 return true;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
497 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
498 if !self.options.list_ignored
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
499 && self.ignore_patterns_have_changed == Some(false)
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
500 {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
501 if let Some(cached_mtime) = cached_directory_mtime {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
502 // The dirstate contains a cached mtime for this directory, set
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
503 // by a previous run of the `status` algorithm which found this
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
504 // directory eligible for `read_dir` caching.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
505 if let Ok(meta) = directory_entry.symlink_metadata() {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
506 if cached_mtime
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
507 .likely_equal_to_mtime_of(&meta)
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
508 .unwrap_or(false)
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
509 {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
510 // The mtime of that directory has not changed
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
511 // since then, which means that the results of
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
512 // `read_dir` should also be unchanged.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
513 return true;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
514 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
515 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
516 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
517 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
518 false
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
519 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
520
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
521 fn should_visit(set: &VisitChildrenSet, basename: &HgPath) -> bool {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
522 match set {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
523 VisitChildrenSet::This | VisitChildrenSet::Recursive => true,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
524 VisitChildrenSet::Empty => false,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
525 VisitChildrenSet::Set(children_to_visit) => {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
526 children_to_visit.contains(basename)
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
527 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
528 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
529 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
530
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
531 /// Returns whether all child entries of the filesystem directory have a
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
532 /// corresponding dirstate node or are ignored.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
533 fn traverse_fs_directory_and_dirstate<'ancestor>(
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
534 &self,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
535 has_ignored_ancestor: &'ancestor HasIgnoredAncestor<'ancestor>,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
536 dirstate_nodes: ChildNodesRef<'tree, 'on_disk>,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
537 directory_hg_path: &BorrowedPath<'tree, 'on_disk>,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
538 directory_entry: &DirEntry,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
539 cached_directory_mtime: Option<TruncatedTimestamp>,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
540 is_at_repo_root: bool,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
541 ) -> Result<bool, DirstateV2ParseError> {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
542 let children_set = self.matcher.visit_children_set(directory_hg_path);
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
543 if let VisitChildrenSet::Empty = children_set {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
544 return Ok(false);
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
545 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
546 if self.can_skip_fs_readdir(directory_entry, cached_directory_mtime) {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
547 dirstate_nodes
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
548 .par_iter()
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
549 .map(|dirstate_node| {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
550 let fs_path = &directory_entry.fs_path;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
551 let basename =
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
552 dirstate_node.base_name(self.dmap.on_disk)?.as_bytes();
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
553 let fs_path = fs_path.join(get_path_from_bytes(basename));
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
554 if !Self::should_visit(
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
555 &children_set,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
556 HgPath::new(basename),
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
557 ) {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
558 return Ok(());
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
559 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
560 match std::fs::symlink_metadata(&fs_path) {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
561 Ok(fs_metadata) => {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
562 let file_type = fs_metadata.file_type().into();
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
563 let entry = DirEntry {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
564 hg_path: Cow::Borrowed(
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
565 dirstate_node
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
566 .full_path(self.dmap.on_disk)?,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
567 ),
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
568 fs_path: Cow::Borrowed(&fs_path),
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
569 symlink_metadata: Some(fs_metadata),
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
570 file_type,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
571 };
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
572 self.traverse_fs_and_dirstate(
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
573 &entry,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
574 dirstate_node,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
575 has_ignored_ancestor,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
576 )
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
577 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
578 Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
579 self.traverse_dirstate_only(dirstate_node)
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
580 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
581 Err(error) => {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
582 let hg_path =
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
583 dirstate_node.full_path(self.dmap.on_disk)?;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
584 self.io_error(error, hg_path);
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
585 Ok(())
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
586 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
587 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
588 })
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
589 .collect::<Result<(), _>>()?;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
590
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
591 // We don’t know, so conservatively say this isn’t the case
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
592 let children_all_have_dirstate_node_or_are_ignored = false;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
593
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
594 return Ok(children_all_have_dirstate_node_or_are_ignored);
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
595 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
596
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
597 let readdir_succeeded;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
598 let mut fs_entries = if let Ok(entries) = self.read_dir(
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
599 directory_hg_path,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
600 &directory_entry.fs_path,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
601 is_at_repo_root,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
602 ) {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
603 readdir_succeeded = true;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
604 entries
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
605 } else {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
606 // Treat an unreadable directory (typically because of insufficient
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
607 // permissions) like an empty directory. `self.read_dir` has
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
608 // already called `self.io_error` so a warning will be emitted.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
609 // We still need to remember that there was an error so that we
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
610 // know not to cache this result.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
611 readdir_succeeded = false;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
612 Vec::new()
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
613 };
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
614
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
615 // `merge_join_by` requires both its input iterators to be sorted:
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
616
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
617 let dirstate_nodes = dirstate_nodes.sorted();
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
618 // `sort_unstable_by_key` doesn’t allow keys borrowing from the value:
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
619 // https://github.com/rust-lang/rust/issues/34162
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
620 fs_entries.sort_unstable_by(|e1, e2| e1.hg_path.cmp(&e2.hg_path));
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
621
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
622 // Propagate here any error that would happen inside the comparison
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
623 // callback below
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
624 for dirstate_node in &dirstate_nodes {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
625 dirstate_node.base_name(self.dmap.on_disk)?;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
626 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
627 itertools::merge_join_by(
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
628 dirstate_nodes,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
629 &fs_entries,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
630 |dirstate_node, fs_entry| {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
631 // This `unwrap` never panics because we already propagated
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
632 // those errors above
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
633 dirstate_node
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
634 .base_name(self.dmap.on_disk)
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
635 .unwrap()
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
636 .cmp(&fs_entry.hg_path)
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
637 },
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
638 )
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
639 .par_bridge()
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
640 .map(|pair| {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
641 use itertools::EitherOrBoth::*;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
642 let basename = match &pair {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
643 Left(dirstate_node) | Both(dirstate_node, _) => HgPath::new(
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
644 dirstate_node.base_name(self.dmap.on_disk)?.as_bytes(),
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
645 ),
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
646 Right(fs_entry) => &fs_entry.hg_path,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
647 };
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
648 if !Self::should_visit(&children_set, basename) {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
649 return Ok(false);
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
650 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
651 let has_dirstate_node_or_is_ignored = match pair {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
652 Both(dirstate_node, fs_entry) => {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
653 self.traverse_fs_and_dirstate(
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
654 fs_entry,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
655 dirstate_node,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
656 has_ignored_ancestor,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
657 )?;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
658 true
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
659 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
660 Left(dirstate_node) => {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
661 self.traverse_dirstate_only(dirstate_node)?;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
662 true
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
663 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
664 Right(fs_entry) => self.traverse_fs_only(
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
665 has_ignored_ancestor.force(&self.ignore_fn),
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
666 directory_hg_path,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
667 fs_entry,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
668 ),
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
669 };
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
670 Ok(has_dirstate_node_or_is_ignored)
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
671 })
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
672 .try_reduce(|| true, |a, b| Ok(a && b))
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
673 .map(|res| res && readdir_succeeded)
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
674 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
675
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
676 fn traverse_fs_and_dirstate<'ancestor>(
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
677 &self,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
678 fs_entry: &DirEntry,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
679 dirstate_node: NodeRef<'tree, 'on_disk>,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
680 has_ignored_ancestor: &'ancestor HasIgnoredAncestor<'ancestor>,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
681 ) -> Result<(), DirstateV2ParseError> {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
682 let outdated_dircache =
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
683 self.check_for_outdated_directory_cache(&dirstate_node)?;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
684 let hg_path = &dirstate_node.full_path_borrowed(self.dmap.on_disk)?;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
685 let file_or_symlink = fs_entry.is_file() || fs_entry.is_symlink();
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
686 if !file_or_symlink {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
687 // If we previously had a file here, it was removed (with
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
688 // `hg rm` or similar) or deleted before it could be
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
689 // replaced by a directory or something else.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
690 self.mark_removed_or_deleted_if_file(&dirstate_node)?;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
691 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
692 if let Some(bad_type) = fs_entry.is_bad() {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
693 if self.matcher.exact_match(hg_path) {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
694 let path = dirstate_node.full_path(self.dmap.on_disk)?;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
695 self.outcome.lock().unwrap().bad.push((
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
696 path.to_owned().into(),
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
697 BadMatch::BadType(bad_type),
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
698 ))
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
699 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
700 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
701 if fs_entry.is_dir() {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
702 if self.options.collect_traversed_dirs {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
703 self.outcome
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
704 .lock()
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
705 .unwrap()
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
706 .traversed
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
707 .push(hg_path.detach_from_tree())
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
708 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
709 let is_ignored = HasIgnoredAncestor::create(
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
710 Some(has_ignored_ancestor),
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
711 hg_path,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
712 );
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
713 let is_at_repo_root = false;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
714 let children_all_have_dirstate_node_or_are_ignored = self
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
715 .traverse_fs_directory_and_dirstate(
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
716 &is_ignored,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
717 dirstate_node.children(self.dmap.on_disk)?,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
718 hg_path,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
719 fs_entry,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
720 dirstate_node.cached_directory_mtime()?,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
721 is_at_repo_root,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
722 )?;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
723 self.maybe_save_directory_mtime(
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
724 children_all_have_dirstate_node_or_are_ignored,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
725 fs_entry,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
726 dirstate_node,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
727 outdated_dircache,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
728 )?
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
729 } else {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
730 if file_or_symlink && self.matcher.matches(hg_path) {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
731 if let Some(entry) = dirstate_node.entry()? {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
732 if !entry.any_tracked() {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
733 // Forward-compat if we start tracking unknown/ignored
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
734 // files for caching reasons
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
735 self.mark_unknown_or_ignored(
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
736 has_ignored_ancestor.force(&self.ignore_fn),
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
737 hg_path,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
738 );
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
739 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
740 if entry.added() {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
741 self.push_outcome(Outcome::Added, &dirstate_node)?;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
742 } else if entry.removed() {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
743 self.push_outcome(Outcome::Removed, &dirstate_node)?;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
744 } else if entry.modified() {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
745 self.push_outcome(Outcome::Modified, &dirstate_node)?;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
746 } else {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
747 self.handle_normal_file(&dirstate_node, fs_entry)?;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
748 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
749 } else {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
750 // `node.entry.is_none()` indicates a "directory"
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
751 // node, but the filesystem has a file
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
752 self.mark_unknown_or_ignored(
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
753 has_ignored_ancestor.force(&self.ignore_fn),
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
754 hg_path,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
755 );
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
756 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
757 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
758
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
759 for child_node in dirstate_node.children(self.dmap.on_disk)?.iter()
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
760 {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
761 self.traverse_dirstate_only(child_node)?
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
762 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
763 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
764 Ok(())
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
765 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
766
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
767 /// Save directory mtime if applicable.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
768 ///
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
769 /// `outdated_directory_cache` is `true` if we've just invalidated the
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
770 /// cache for this directory in `check_for_outdated_directory_cache`,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
771 /// which forces the update.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
772 fn maybe_save_directory_mtime(
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
773 &self,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
774 children_all_have_dirstate_node_or_are_ignored: bool,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
775 directory_entry: &DirEntry,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
776 dirstate_node: NodeRef<'tree, 'on_disk>,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
777 outdated_directory_cache: bool,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
778 ) -> Result<(), DirstateV2ParseError> {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
779 if !children_all_have_dirstate_node_or_are_ignored {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
780 return Ok(());
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
781 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
782 // All filesystem directory entries from `read_dir` have a
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
783 // corresponding node in the dirstate, so we can reconstitute the
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
784 // names of those entries without calling `read_dir` again.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
785
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
786 // TODO: use let-else here and below when available:
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
787 // https://github.com/rust-lang/rust/issues/87335
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
788 let status_start = if let Some(status_start) =
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
789 &self.filesystem_time_at_status_start
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
790 {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
791 status_start
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
792 } else {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
793 return Ok(());
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
794 };
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
795
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
796 // Although the Rust standard library’s `SystemTime` type
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
797 // has nanosecond precision, the times reported for a
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
798 // directory’s (or file’s) modified time may have lower
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
799 // resolution based on the filesystem (for example ext3
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
800 // only stores integer seconds), kernel (see
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
801 // https://stackoverflow.com/a/14393315/1162888), etc.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
802 let metadata = match directory_entry.symlink_metadata() {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
803 Ok(meta) => meta,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
804 Err(_) => return Ok(()),
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
805 };
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
806
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
807 let directory_mtime = match TruncatedTimestamp::for_reliable_mtime_of(
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
808 &metadata,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
809 status_start,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
810 ) {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
811 Ok(Some(directory_mtime)) => directory_mtime,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
812 Ok(None) => {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
813 // The directory was modified too recently,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
814 // don’t cache its `read_dir` results.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
815 //
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
816 // 1. A change to this directory (direct child was added or
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
817 // removed) cause its mtime to be set (possibly truncated)
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
818 // to `directory_mtime`
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
819 // 2. This `status` algorithm calls `read_dir`
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
820 // 3. An other change is made to the same directory is made so
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
821 // that calling `read_dir` agin would give different
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
822 // results, but soon enough after 1. that the mtime stays
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
823 // the same
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
824 //
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
825 // On a system where the time resolution poor, this
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
826 // scenario is not unlikely if all three steps are caused
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
827 // by the same script.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
828 return Ok(());
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
829 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
830 Err(_) => {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
831 // OS/libc does not support mtime?
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
832 return Ok(());
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
833 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
834 };
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
835 // We’ve observed (through `status_start`) that time has
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
836 // “progressed” since `directory_mtime`, so any further
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
837 // change to this directory is extremely likely to cause a
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
838 // different mtime.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
839 //
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
840 // Having the same mtime again is not entirely impossible
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
841 // since the system clock is not monotonous. It could jump
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
842 // backward to some point before `directory_mtime`, then a
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
843 // directory change could potentially happen during exactly
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
844 // the wrong tick.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
845 //
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
846 // We deem this scenario (unlike the previous one) to be
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
847 // unlikely enough in practice.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
848
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
849 let is_up_to_date = if let Some(cached) =
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
850 dirstate_node.cached_directory_mtime()?
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
851 {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
852 !outdated_directory_cache && cached.likely_equal(directory_mtime)
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
853 } else {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
854 false
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
855 };
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
856 if !is_up_to_date {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
857 let hg_path = dirstate_node
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
858 .full_path_borrowed(self.dmap.on_disk)?
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
859 .detach_from_tree();
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
860 self.new_cacheable_directories
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
861 .lock()
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
862 .unwrap()
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
863 .push((hg_path, directory_mtime))
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
864 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
865 Ok(())
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
866 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
867
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
868 /// A file that is clean in the dirstate was found in the filesystem
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
869 fn handle_normal_file(
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
870 &self,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
871 dirstate_node: &NodeRef<'tree, 'on_disk>,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
872 fs_entry: &DirEntry,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
873 ) -> Result<(), DirstateV2ParseError> {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
874 // Keep the low 31 bits
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
875 fn truncate_u64(value: u64) -> i32 {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
876 (value & 0x7FFF_FFFF) as i32
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
877 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
878
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
879 let fs_metadata = match fs_entry.symlink_metadata() {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
880 Ok(meta) => meta,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
881 Err(_) => return Ok(()),
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
882 };
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
883
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
884 let entry = dirstate_node
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
885 .entry()?
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
886 .expect("handle_normal_file called with entry-less node");
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
887 let mode_changed =
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
888 || self.options.check_exec && entry.mode_changed(&fs_metadata);
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
889 let size = entry.size();
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
890 let size_changed = size != truncate_u64(fs_metadata.len());
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
891 if size >= 0 && size_changed && fs_metadata.file_type().is_symlink() {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
892 // issue6456: Size returned may be longer due to encryption
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
893 // on EXT-4 fscrypt. TODO maybe only do it on EXT4?
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
894 self.push_outcome(Outcome::Unsure, dirstate_node)?
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
895 } else if dirstate_node.has_copy_source()
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
896 || entry.is_from_other_parent()
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
897 || (size >= 0 && (size_changed || mode_changed()))
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
898 {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
899 self.push_outcome(Outcome::Modified, dirstate_node)?
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
900 } else {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
901 let mtime_looks_clean = if let Some(dirstate_mtime) =
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
902 entry.truncated_mtime()
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
903 {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
904 let fs_mtime = TruncatedTimestamp::for_mtime_of(&fs_metadata)
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
905 .expect("OS/libc does not support mtime?");
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
906 // There might be a change in the future if for example the
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
907 // internal clock become off while process run, but this is a
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
908 // case where the issues the user would face
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
909 // would be a lot worse and there is nothing we
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
910 // can really do.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
911 fs_mtime.likely_equal(dirstate_mtime)
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
912 } else {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
913 // No mtime in the dirstate entry
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
914 false
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
915 };
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
916 if !mtime_looks_clean {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
917 self.push_outcome(Outcome::Unsure, dirstate_node)?
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
918 } else if self.options.list_clean {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
919 self.push_outcome(Outcome::Clean, dirstate_node)?
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
920 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
921 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
922 Ok(())
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
923 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
924
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
925 /// A node in the dirstate tree has no corresponding filesystem entry
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
926 fn traverse_dirstate_only(
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
927 &self,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
928 dirstate_node: NodeRef<'tree, 'on_disk>,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
929 ) -> Result<(), DirstateV2ParseError> {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
930 self.check_for_outdated_directory_cache(&dirstate_node)?;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
931 self.mark_removed_or_deleted_if_file(&dirstate_node)?;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
932 dirstate_node
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
933 .children(self.dmap.on_disk)?
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
934 .par_iter()
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
935 .map(|child_node| self.traverse_dirstate_only(child_node))
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
936 .collect()
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
937 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
938
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
939 /// A node in the dirstate tree has no corresponding *file* on the
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
940 /// filesystem
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
941 ///
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
942 /// Does nothing on a "directory" node
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
943 fn mark_removed_or_deleted_if_file(
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
944 &self,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
945 dirstate_node: &NodeRef<'tree, 'on_disk>,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
946 ) -> Result<(), DirstateV2ParseError> {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
947 if let Some(entry) = dirstate_node.entry()? {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
948 if !entry.any_tracked() {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
949 // Future-compat for when we start storing ignored and unknown
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
950 // files for caching reasons
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
951 return Ok(());
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
952 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
953 let path = dirstate_node.full_path(self.dmap.on_disk)?;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
954 if self.matcher.matches(path) {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
955 if entry.removed() {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
956 self.push_outcome(Outcome::Removed, dirstate_node)?
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
957 } else {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
958 self.push_outcome(Outcome::Deleted, dirstate_node)?
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
959 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
960 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
961 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
962 Ok(())
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
963 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
964
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
965 /// Something in the filesystem has no corresponding dirstate node
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
966 ///
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
967 /// Returns whether that path is ignored
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
968 fn traverse_fs_only(
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
969 &self,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
970 has_ignored_ancestor: bool,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
971 directory_hg_path: &HgPath,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
972 fs_entry: &DirEntry,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
973 ) -> bool {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
974 let hg_path = directory_hg_path.join(&fs_entry.hg_path);
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
975 let file_or_symlink = fs_entry.is_file() || fs_entry.is_symlink();
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
976 if fs_entry.is_dir() {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
977 let is_ignored =
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
978 has_ignored_ancestor || (self.ignore_fn)(&hg_path);
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
979 let traverse_children = if is_ignored {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
980 // Descendants of an ignored directory are all ignored
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
981 self.options.list_ignored
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
982 } else {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
983 // Descendants of an unknown directory may be either unknown or
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
984 // ignored
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
985 self.options.list_unknown || self.options.list_ignored
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
986 };
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
987 if traverse_children {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
988 let is_at_repo_root = false;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
989 if let Ok(children_fs_entries) =
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
990 self.read_dir(&hg_path, &fs_entry.fs_path, is_at_repo_root)
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
991 {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
992 children_fs_entries.par_iter().for_each(|child_fs_entry| {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
993 self.traverse_fs_only(
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
994 is_ignored,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
995 &hg_path,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
996 child_fs_entry,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
997 );
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
998 })
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
999 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1000 if self.options.collect_traversed_dirs {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1001 self.outcome.lock().unwrap().traversed.push(hg_path.into())
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1002 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1003 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1004 is_ignored
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1005 } else if file_or_symlink {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1006 if self.matcher.matches(&hg_path) {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1007 self.mark_unknown_or_ignored(
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1008 has_ignored_ancestor,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1009 &BorrowedPath::InMemory(&hg_path),
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1010 )
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1011 } else {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1012 // We haven’t computed whether this path is ignored. It
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1013 // might not be, and a future run of status might have a
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1014 // different matcher that matches it. So treat it as not
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1015 // ignored. That is, inhibit readdir caching of the parent
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1016 // directory.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1017 false
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1018 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1019 } else {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1020 // This is neither a directory, a plain file, or a symlink.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1021 // Treat it like an ignored file.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1022 true
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1023 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1024 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1025
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1026 /// Returns whether that path is ignored
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1027 fn mark_unknown_or_ignored(
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1028 &self,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1029 has_ignored_ancestor: bool,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1030 hg_path: &BorrowedPath<'_, 'on_disk>,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1031 ) -> bool {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1032 let is_ignored = has_ignored_ancestor || (self.ignore_fn)(hg_path);
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1033 if is_ignored {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1034 if self.options.list_ignored {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1035 self.push_outcome_without_copy_source(
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1036 Outcome::Ignored,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1037 hg_path,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1038 )
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1039 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1040 } else if self.options.list_unknown {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1041 self.push_outcome_without_copy_source(Outcome::Unknown, hg_path)
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1042 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1043 is_ignored
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1044 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1045 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1046
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1047 /// Since [`std::fs::FileType`] cannot be built directly, we emulate what we
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1048 /// care about.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1049 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1050 enum FakeFileType {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1051 File,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1052 Directory,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1053 Symlink,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1054 BadType(BadType),
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1055 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1056
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1057 impl From<std::fs::FileType> for FakeFileType {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1058 fn from(f: std::fs::FileType) -> Self {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1059 if f.is_dir() {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1060 Self::Directory
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1061 } else if f.is_file() {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1062 Self::File
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1063 } else if f.is_symlink() {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1064 Self::Symlink
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1065 } else if f.is_fifo() {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1066 Self::BadType(BadType::FIFO)
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1067 } else if f.is_block_device() {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1068 Self::BadType(BadType::BlockDevice)
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1069 } else if f.is_char_device() {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1070 Self::BadType(BadType::CharacterDevice)
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1071 } else if f.is_socket() {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1072 Self::BadType(BadType::Socket)
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1073 } else {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1074 Self::BadType(BadType::Unknown)
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1075 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1076 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1077 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1078
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1079 struct DirEntry<'a> {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1080 /// Path as stored in the dirstate, or just the filename for optimization.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1081 hg_path: HgPathCow<'a>,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1082 /// Filesystem path
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1083 fs_path: Cow<'a, Path>,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1084 /// Lazily computed
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1085 symlink_metadata: Option<std::fs::Metadata>,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1086 /// Already computed for ergonomics.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1087 file_type: FakeFileType,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1088 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1089
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1090 impl<'a> DirEntry<'a> {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1091 /// Returns **unsorted** entries in the given directory, with name,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1092 /// metadata and file type.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1093 ///
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1094 /// If a `.hg` sub-directory is encountered:
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1095 ///
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1096 /// * At the repository root, ignore that sub-directory
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1097 /// * Elsewhere, we’re listing the content of a sub-repo. Return an empty
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1098 /// list instead.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1099 fn read_dir(path: &Path, is_at_repo_root: bool) -> io::Result<Vec<Self>> {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1100 // `read_dir` returns a "not found" error for the empty path
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1101 let at_cwd = path == Path::new("");
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1102 let read_dir_path = if at_cwd { Path::new(".") } else { path };
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1103 let mut results = Vec::new();
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1104 for entry in read_dir_path.read_dir()? {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1105 let entry = entry?;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1106 let file_type = match entry.file_type() {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1107 Ok(v) => v,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1108 Err(e) => {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1109 // race with file deletion?
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1110 if e.kind() == std::io::ErrorKind::NotFound {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1111 continue;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1112 } else {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1113 return Err(e);
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1114 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1115 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1116 };
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1117 let file_name = entry.file_name();
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1118 // FIXME don't do this when cached
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1119 if file_name == ".hg" {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1120 if is_at_repo_root {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1121 // Skip the repo’s own .hg (might be a symlink)
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1122 continue;
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1123 } else if file_type.is_dir() {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1124 // A .hg sub-directory at another location means a subrepo,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1125 // skip it entirely.
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1126 return Ok(Vec::new());
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1127 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1128 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1129 let full_path = if at_cwd {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1130 file_name.clone().into()
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1131 } else {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1132 entry.path()
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1133 };
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1134 let filename =
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1135 Cow::Owned(get_bytes_from_os_string(file_name).into());
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1136 let file_type = FakeFileType::from(file_type);
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1137 results.push(DirEntry {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1138 hg_path: filename,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1139 fs_path: Cow::Owned(full_path.to_path_buf()),
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1140 symlink_metadata: None,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1141 file_type,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1142 })
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1143 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1144 Ok(results)
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1145 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1146
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1147 fn symlink_metadata(&self) -> Result<std::fs::Metadata, std::io::Error> {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1148 match &self.symlink_metadata {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1149 Some(meta) => Ok(meta.clone()),
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1150 None => std::fs::symlink_metadata(&self.fs_path),
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1151 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1152 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1153
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1154 fn is_dir(&self) -> bool {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1155 self.file_type == FakeFileType::Directory
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1156 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1157
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1158 fn is_file(&self) -> bool {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1159 self.file_type == FakeFileType::File
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1160 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1161
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1162 fn is_symlink(&self) -> bool {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1163 self.file_type == FakeFileType::Symlink
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1164 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1165
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1166 fn is_bad(&self) -> Option<BadType> {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1167 match self.file_type {
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1168 FakeFileType::BadType(ty) => Some(ty),
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1169 _ => None,
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1170 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1171 }
db065b33fa56 rust-dirstate: merge `dirstate_tree` module into `dirstate`
Raphaël Gomès <rgomes@octobus.net>
parents: 50862
diff changeset
1172 }