Mercurial > public > mercurial-scm > hg-stable
annotate rust/hg-core/src/dirstate_tree/status.rs @ 49927:e0c0545e2e55
branching: merge stable into default
author | Rapha?l Gom?s <rgomes@octobus.net> |
---|---|
date | Wed, 04 Jan 2023 16:02:22 +0100 |
parents | c7fb9b74e753 c52435820bbd |
children | c15b415d1bff |
rev | line source |
---|---|
48205
320de901896a
dirstate-v2: Truncate directory mtimes to 31 bits of seconds
Simon Sapin <simon.sapin@octobus.net>
parents:
48204
diff
changeset
|
1 use crate::dirstate::entry::TruncatedTimestamp; |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
2 use crate::dirstate::status::IgnoreFnType; |
48493
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
3 use crate::dirstate::status::StatusPath; |
47353
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47352
diff
changeset
|
4 use crate::dirstate_tree::dirstate_map::BorrowedPath; |
47341
69530e5d4fe5
dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents:
47339
diff
changeset
|
5 use crate::dirstate_tree::dirstate_map::ChildNodesRef; |
47126
d5956136d19d
dirstate-tree: Give to `status()` mutable access to the `DirstateMap`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
6 use crate::dirstate_tree::dirstate_map::DirstateMap; |
48893
6cd249556e20
rust-status: don't trigger dirstate v1 rewrite when only v2 data is changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48825
diff
changeset
|
7 use crate::dirstate_tree::dirstate_map::DirstateVersion; |
47341
69530e5d4fe5
dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents:
47339
diff
changeset
|
8 use crate::dirstate_tree::dirstate_map::NodeRef; |
47343
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47341
diff
changeset
|
9 use crate::dirstate_tree::on_disk::DirstateV2ParseError; |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
10 use crate::matchers::get_ignore_function; |
47126
d5956136d19d
dirstate-tree: Give to `status()` mutable access to the `DirstateMap`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
11 use crate::matchers::Matcher; |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
12 use crate::utils::files::get_bytes_from_os_string; |
49550
363923bd51cd
dirstate-v2: hash the source of the ignore patterns as well
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49547
diff
changeset
|
13 use crate::utils::files::get_bytes_from_path; |
47346
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47344
diff
changeset
|
14 use crate::utils::files::get_path_from_bytes; |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
15 use crate::utils::hg_path::HgPath; |
47129
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47128
diff
changeset
|
16 use crate::BadMatch; |
47126
d5956136d19d
dirstate-tree: Give to `status()` mutable access to the `DirstateMap`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
17 use crate::DirstateStatus; |
48493
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
18 use crate::HgPathCow; |
47126
d5956136d19d
dirstate-tree: Give to `status()` mutable access to the `DirstateMap`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
19 use crate::PatternFileWarning; |
d5956136d19d
dirstate-tree: Give to `status()` mutable access to the `DirstateMap`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
20 use crate::StatusError; |
d5956136d19d
dirstate-tree: Give to `status()` mutable access to the `DirstateMap`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
21 use crate::StatusOptions; |
47132
c92e63762573
dirstate-tree: Add #[timed] attribute to `status` and `DirstateMap::read`
Simon Sapin <simon.sapin@octobus.net>
parents:
47131
diff
changeset
|
22 use micro_timer::timed; |
49524
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
23 use once_cell::sync::OnceCell; |
47131
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47129
diff
changeset
|
24 use rayon::prelude::*; |
47415
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47356
diff
changeset
|
25 use sha1::{Digest, Sha1}; |
47355
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
26 use std::borrow::Cow; |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
27 use std::io; |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
28 use std::path::Path; |
47126
d5956136d19d
dirstate-tree: Give to `status()` mutable access to the `DirstateMap`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
29 use std::path::PathBuf; |
47131
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47129
diff
changeset
|
30 use std::sync::Mutex; |
47355
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
31 use std::time::SystemTime; |
47126
d5956136d19d
dirstate-tree: Give to `status()` mutable access to the `DirstateMap`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
32 |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
33 /// Returns the status of the working directory compared to its parent |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
34 /// changeset. |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
35 /// |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
36 /// This algorithm is based on traversing the filesystem tree (`fs` in function |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
37 /// and variable names) and dirstate tree at the same time. The core of this |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
38 /// traversal is the recursive `traverse_fs_directory_and_dirstate` function |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
39 /// and its use of `itertools::merge_join_by`. When reaching a path that only |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
40 /// exists in one of the two trees, depending on information requested by |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
41 /// `options` we may need to traverse the remaining subtree. |
47132
c92e63762573
dirstate-tree: Add #[timed] attribute to `status` and `DirstateMap::read`
Simon Sapin <simon.sapin@octobus.net>
parents:
47131
diff
changeset
|
42 #[timed] |
48825
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48812
diff
changeset
|
43 pub fn status<'dirstate>( |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48812
diff
changeset
|
44 dmap: &'dirstate mut DirstateMap, |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
45 matcher: &(dyn Matcher + Sync), |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
46 root_dir: PathBuf, |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
47 ignore_files: Vec<PathBuf>, |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
48 options: StatusOptions, |
48825
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48812
diff
changeset
|
49 ) -> Result<(DirstateStatus<'dirstate>, Vec<PatternFileWarning>), StatusError> |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48812
diff
changeset
|
50 { |
48812
e2f8ed37201c
rust-status: cap the number of concurrent threads to 16
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48794
diff
changeset
|
51 // Force the global rayon threadpool to not exceed 16 concurrent threads. |
e2f8ed37201c
rust-status: cap the number of concurrent threads to 16
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48794
diff
changeset
|
52 // This is a stop-gap measure until we figure out why using more than 16 |
e2f8ed37201c
rust-status: cap the number of concurrent threads to 16
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48794
diff
changeset
|
53 // threads makes `status` slower for each additional thread. |
e2f8ed37201c
rust-status: cap the number of concurrent threads to 16
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48794
diff
changeset
|
54 // We use `ok()` in case the global threadpool has already been |
e2f8ed37201c
rust-status: cap the number of concurrent threads to 16
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48794
diff
changeset
|
55 // instantiated in `rhg` or some other caller. |
e2f8ed37201c
rust-status: cap the number of concurrent threads to 16
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48794
diff
changeset
|
56 // TODO find the underlying cause and fix it, then remove this. |
e2f8ed37201c
rust-status: cap the number of concurrent threads to 16
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48794
diff
changeset
|
57 rayon::ThreadPoolBuilder::new() |
49597
c52435820bbd
rust-status: fix thread count ceiling
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49550
diff
changeset
|
58 .num_threads(16.min(rayon::current_num_threads())) |
48812
e2f8ed37201c
rust-status: cap the number of concurrent threads to 16
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48794
diff
changeset
|
59 .build_global() |
e2f8ed37201c
rust-status: cap the number of concurrent threads to 16
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48794
diff
changeset
|
60 .ok(); |
e2f8ed37201c
rust-status: cap the number of concurrent threads to 16
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48794
diff
changeset
|
61 |
47415
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47356
diff
changeset
|
62 let (ignore_fn, warnings, patterns_changed): (IgnoreFnType, _, _) = |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
63 if options.list_ignored || options.list_unknown { |
48893
6cd249556e20
rust-status: don't trigger dirstate v1 rewrite when only v2 data is changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48825
diff
changeset
|
64 let (ignore_fn, warnings, changed) = match dmap.dirstate_version { |
6cd249556e20
rust-status: don't trigger dirstate v1 rewrite when only v2 data is changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48825
diff
changeset
|
65 DirstateVersion::V1 => { |
6cd249556e20
rust-status: don't trigger dirstate v1 rewrite when only v2 data is changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48825
diff
changeset
|
66 let (ignore_fn, warnings) = get_ignore_function( |
6cd249556e20
rust-status: don't trigger dirstate v1 rewrite when only v2 data is changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48825
diff
changeset
|
67 ignore_files, |
6cd249556e20
rust-status: don't trigger dirstate v1 rewrite when only v2 data is changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48825
diff
changeset
|
68 &root_dir, |
49550
363923bd51cd
dirstate-v2: hash the source of the ignore patterns as well
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49547
diff
changeset
|
69 &mut |_source, _pattern_bytes| {}, |
48893
6cd249556e20
rust-status: don't trigger dirstate v1 rewrite when only v2 data is changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48825
diff
changeset
|
70 )?; |
6cd249556e20
rust-status: don't trigger dirstate v1 rewrite when only v2 data is changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48825
diff
changeset
|
71 (ignore_fn, warnings, None) |
6cd249556e20
rust-status: don't trigger dirstate v1 rewrite when only v2 data is changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48825
diff
changeset
|
72 } |
6cd249556e20
rust-status: don't trigger dirstate v1 rewrite when only v2 data is changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48825
diff
changeset
|
73 DirstateVersion::V2 => { |
6cd249556e20
rust-status: don't trigger dirstate v1 rewrite when only v2 data is changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48825
diff
changeset
|
74 let mut hasher = Sha1::new(); |
6cd249556e20
rust-status: don't trigger dirstate v1 rewrite when only v2 data is changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48825
diff
changeset
|
75 let (ignore_fn, warnings) = get_ignore_function( |
6cd249556e20
rust-status: don't trigger dirstate v1 rewrite when only v2 data is changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48825
diff
changeset
|
76 ignore_files, |
6cd249556e20
rust-status: don't trigger dirstate v1 rewrite when only v2 data is changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48825
diff
changeset
|
77 &root_dir, |
49550
363923bd51cd
dirstate-v2: hash the source of the ignore patterns as well
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49547
diff
changeset
|
78 &mut |source, pattern_bytes| { |
363923bd51cd
dirstate-v2: hash the source of the ignore patterns as well
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49547
diff
changeset
|
79 // If inside the repo, use the relative version to |
363923bd51cd
dirstate-v2: hash the source of the ignore patterns as well
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49547
diff
changeset
|
80 // make it deterministic inside tests. |
363923bd51cd
dirstate-v2: hash the source of the ignore patterns as well
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49547
diff
changeset
|
81 // The performance hit should be negligible. |
363923bd51cd
dirstate-v2: hash the source of the ignore patterns as well
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49547
diff
changeset
|
82 let source = source |
363923bd51cd
dirstate-v2: hash the source of the ignore patterns as well
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49547
diff
changeset
|
83 .strip_prefix(&root_dir) |
363923bd51cd
dirstate-v2: hash the source of the ignore patterns as well
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49547
diff
changeset
|
84 .unwrap_or(source); |
363923bd51cd
dirstate-v2: hash the source of the ignore patterns as well
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49547
diff
changeset
|
85 let source = get_bytes_from_path(source); |
363923bd51cd
dirstate-v2: hash the source of the ignore patterns as well
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49547
diff
changeset
|
86 |
363923bd51cd
dirstate-v2: hash the source of the ignore patterns as well
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49547
diff
changeset
|
87 let mut subhasher = Sha1::new(); |
363923bd51cd
dirstate-v2: hash the source of the ignore patterns as well
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49547
diff
changeset
|
88 subhasher.update(pattern_bytes); |
363923bd51cd
dirstate-v2: hash the source of the ignore patterns as well
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49547
diff
changeset
|
89 let patterns_hash = subhasher.finalize(); |
363923bd51cd
dirstate-v2: hash the source of the ignore patterns as well
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49547
diff
changeset
|
90 |
363923bd51cd
dirstate-v2: hash the source of the ignore patterns as well
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49547
diff
changeset
|
91 hasher.update(source); |
363923bd51cd
dirstate-v2: hash the source of the ignore patterns as well
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49547
diff
changeset
|
92 hasher.update(b" "); |
363923bd51cd
dirstate-v2: hash the source of the ignore patterns as well
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49547
diff
changeset
|
93 hasher.update(patterns_hash); |
363923bd51cd
dirstate-v2: hash the source of the ignore patterns as well
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49547
diff
changeset
|
94 hasher.update(b"\n"); |
363923bd51cd
dirstate-v2: hash the source of the ignore patterns as well
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49547
diff
changeset
|
95 }, |
48893
6cd249556e20
rust-status: don't trigger dirstate v1 rewrite when only v2 data is changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48825
diff
changeset
|
96 )?; |
6cd249556e20
rust-status: don't trigger dirstate v1 rewrite when only v2 data is changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48825
diff
changeset
|
97 let new_hash = *hasher.finalize().as_ref(); |
6cd249556e20
rust-status: don't trigger dirstate v1 rewrite when only v2 data is changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48825
diff
changeset
|
98 let changed = new_hash != dmap.ignore_patterns_hash; |
6cd249556e20
rust-status: don't trigger dirstate v1 rewrite when only v2 data is changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48825
diff
changeset
|
99 dmap.ignore_patterns_hash = new_hash; |
6cd249556e20
rust-status: don't trigger dirstate v1 rewrite when only v2 data is changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48825
diff
changeset
|
100 (ignore_fn, warnings, Some(changed)) |
6cd249556e20
rust-status: don't trigger dirstate v1 rewrite when only v2 data is changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48825
diff
changeset
|
101 } |
6cd249556e20
rust-status: don't trigger dirstate v1 rewrite when only v2 data is changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48825
diff
changeset
|
102 }; |
6cd249556e20
rust-status: don't trigger dirstate v1 rewrite when only v2 data is changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48825
diff
changeset
|
103 (ignore_fn, warnings, changed) |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
104 } else { |
47415
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47356
diff
changeset
|
105 (Box::new(|&_| true), vec![], None) |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
106 }; |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
107 |
48538
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
108 let filesystem_time_at_status_start = |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
109 filesystem_now(&root_dir).ok().map(TruncatedTimestamp::from); |
48750
94e36b230990
status: prefer relative paths in Rust code
Simon Sapin <simon.sapin@octobus.net>
parents:
48538
diff
changeset
|
110 |
94e36b230990
status: prefer relative paths in Rust code
Simon Sapin <simon.sapin@octobus.net>
parents:
48538
diff
changeset
|
111 // If the repository is under the current directory, prefer using a |
94e36b230990
status: prefer relative paths in Rust code
Simon Sapin <simon.sapin@octobus.net>
parents:
48538
diff
changeset
|
112 // relative path, so the kernel needs to traverse fewer directory in every |
94e36b230990
status: prefer relative paths in Rust code
Simon Sapin <simon.sapin@octobus.net>
parents:
48538
diff
changeset
|
113 // call to `read_dir` or `symlink_metadata`. |
94e36b230990
status: prefer relative paths in Rust code
Simon Sapin <simon.sapin@octobus.net>
parents:
48538
diff
changeset
|
114 // This is effective in the common case where the current directory is the |
94e36b230990
status: prefer relative paths in Rust code
Simon Sapin <simon.sapin@octobus.net>
parents:
48538
diff
changeset
|
115 // repository root. |
94e36b230990
status: prefer relative paths in Rust code
Simon Sapin <simon.sapin@octobus.net>
parents:
48538
diff
changeset
|
116 |
94e36b230990
status: prefer relative paths in Rust code
Simon Sapin <simon.sapin@octobus.net>
parents:
48538
diff
changeset
|
117 // TODO: Better yet would be to use libc functions like `openat` and |
94e36b230990
status: prefer relative paths in Rust code
Simon Sapin <simon.sapin@octobus.net>
parents:
48538
diff
changeset
|
118 // `fstatat` to remove such repeated traversals entirely, but the standard |
94e36b230990
status: prefer relative paths in Rust code
Simon Sapin <simon.sapin@octobus.net>
parents:
48538
diff
changeset
|
119 // library does not provide APIs based on those. |
94e36b230990
status: prefer relative paths in Rust code
Simon Sapin <simon.sapin@octobus.net>
parents:
48538
diff
changeset
|
120 // Maybe with a crate like https://crates.io/crates/openat instead? |
94e36b230990
status: prefer relative paths in Rust code
Simon Sapin <simon.sapin@octobus.net>
parents:
48538
diff
changeset
|
121 let root_dir = if let Some(relative) = std::env::current_dir() |
94e36b230990
status: prefer relative paths in Rust code
Simon Sapin <simon.sapin@octobus.net>
parents:
48538
diff
changeset
|
122 .ok() |
94e36b230990
status: prefer relative paths in Rust code
Simon Sapin <simon.sapin@octobus.net>
parents:
48538
diff
changeset
|
123 .and_then(|cwd| root_dir.strip_prefix(cwd).ok()) |
94e36b230990
status: prefer relative paths in Rust code
Simon Sapin <simon.sapin@octobus.net>
parents:
48538
diff
changeset
|
124 { |
94e36b230990
status: prefer relative paths in Rust code
Simon Sapin <simon.sapin@octobus.net>
parents:
48538
diff
changeset
|
125 relative |
94e36b230990
status: prefer relative paths in Rust code
Simon Sapin <simon.sapin@octobus.net>
parents:
48538
diff
changeset
|
126 } else { |
94e36b230990
status: prefer relative paths in Rust code
Simon Sapin <simon.sapin@octobus.net>
parents:
48538
diff
changeset
|
127 &root_dir |
94e36b230990
status: prefer relative paths in Rust code
Simon Sapin <simon.sapin@octobus.net>
parents:
48538
diff
changeset
|
128 }; |
94e36b230990
status: prefer relative paths in Rust code
Simon Sapin <simon.sapin@octobus.net>
parents:
48538
diff
changeset
|
129 |
48468
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48439
diff
changeset
|
130 let outcome = DirstateStatus { |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48439
diff
changeset
|
131 filesystem_time_at_status_start, |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48439
diff
changeset
|
132 ..Default::default() |
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48439
diff
changeset
|
133 }; |
47131
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47129
diff
changeset
|
134 let common = StatusCommon { |
47344
8d0260d0dbc9
dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents:
47343
diff
changeset
|
135 dmap, |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
136 options, |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
137 matcher, |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
138 ignore_fn, |
48468
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48439
diff
changeset
|
139 outcome: Mutex::new(outcome), |
47415
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47356
diff
changeset
|
140 ignore_patterns_have_changed: patterns_changed, |
49546
ecf9788cd9c4
rust-status: fix typos and add docstrings to dircache related fields
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49524
diff
changeset
|
141 new_cacheable_directories: Default::default(), |
ecf9788cd9c4
rust-status: fix typos and add docstrings to dircache related fields
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49524
diff
changeset
|
142 outdated_cached_directories: Default::default(), |
48468
000130cfafb6
rhg: Update the dirstate on disk after status
Simon Sapin <simon.sapin@octobus.net>
parents:
48439
diff
changeset
|
143 filesystem_time_at_status_start, |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
144 }; |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
145 let is_at_repo_root = true; |
47353
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47352
diff
changeset
|
146 let hg_path = &BorrowedPath::OnDisk(HgPath::new("")); |
49524
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
147 let has_ignored_ancestor = HasIgnoredAncestor::create(None, hg_path); |
47355
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
148 let root_cached_mtime = None; |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
149 // If the path we have for the repository root is a symlink, do follow it. |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
150 // (As opposed to symlinks within the working directory which are not |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
151 // followed, using `std::fs::symlink_metadata`.) |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
152 common.traverse_fs_directory_and_dirstate( |
49524
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
153 &has_ignored_ancestor, |
47341
69530e5d4fe5
dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents:
47339
diff
changeset
|
154 dmap.root.as_ref(), |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
155 hg_path, |
49718
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
156 &DirEntry { |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
157 hg_path: Cow::Borrowed(HgPath::new(b"")), |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
158 fs_path: Cow::Borrowed(&root_dir), |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
159 symlink_metadata: None, |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
160 file_type: FakeFileType::Directory, |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
161 }, |
47355
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
162 root_cached_mtime, |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
163 is_at_repo_root, |
47343
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47341
diff
changeset
|
164 )?; |
47356
04d1f17f49e7
dirstate-v2: Write .hg/dirstate back to disk on directory cache changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47355
diff
changeset
|
165 let mut outcome = common.outcome.into_inner().unwrap(); |
49546
ecf9788cd9c4
rust-status: fix typos and add docstrings to dircache related fields
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49524
diff
changeset
|
166 let new_cacheable = common.new_cacheable_directories.into_inner().unwrap(); |
ecf9788cd9c4
rust-status: fix typos and add docstrings to dircache related fields
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49524
diff
changeset
|
167 let outdated = common.outdated_cached_directories.into_inner().unwrap(); |
47415
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47356
diff
changeset
|
168 |
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47356
diff
changeset
|
169 outcome.dirty = common.ignore_patterns_have_changed == Some(true) |
47479
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47415
diff
changeset
|
170 || !outdated.is_empty() |
49546
ecf9788cd9c4
rust-status: fix typos and add docstrings to dircache related fields
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49524
diff
changeset
|
171 || (!new_cacheable.is_empty() |
48893
6cd249556e20
rust-status: don't trigger dirstate v1 rewrite when only v2 data is changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48825
diff
changeset
|
172 && dmap.dirstate_version == DirstateVersion::V2); |
47415
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47356
diff
changeset
|
173 |
47479
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47415
diff
changeset
|
174 // Remove outdated mtimes before adding new mtimes, in case a given |
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47415
diff
changeset
|
175 // directory is both |
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47415
diff
changeset
|
176 for path in &outdated { |
49182
f3e8b0b0a8c2
rust-dirstatemap: add `clear_cached_mtime` helper method
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48825
diff
changeset
|
177 dmap.clear_cached_mtime(path)?; |
47479
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47415
diff
changeset
|
178 } |
49546
ecf9788cd9c4
rust-status: fix typos and add docstrings to dircache related fields
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49524
diff
changeset
|
179 for (path, mtime) in &new_cacheable { |
49183
464747faef14
rust-dirstatemap: add `set_cached_mtime` helper method
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49182
diff
changeset
|
180 dmap.set_cached_mtime(path, *mtime)?; |
47355
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
181 } |
47415
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47356
diff
changeset
|
182 |
47355
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
183 Ok((outcome, warnings)) |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
184 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
185 |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
186 /// Bag of random things needed by various parts of the algorithm. Reduces the |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
187 /// number of parameters passed to functions. |
47353
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47352
diff
changeset
|
188 struct StatusCommon<'a, 'tree, 'on_disk: 'tree> { |
47344
8d0260d0dbc9
dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents:
47343
diff
changeset
|
189 dmap: &'tree DirstateMap<'on_disk>, |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
190 options: StatusOptions, |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
191 matcher: &'a (dyn Matcher + Sync), |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
192 ignore_fn: IgnoreFnType<'a>, |
47353
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47352
diff
changeset
|
193 outcome: Mutex<DirstateStatus<'on_disk>>, |
49546
ecf9788cd9c4
rust-status: fix typos and add docstrings to dircache related fields
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49524
diff
changeset
|
194 /// New timestamps of directories to be used for caching their readdirs |
ecf9788cd9c4
rust-status: fix typos and add docstrings to dircache related fields
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49524
diff
changeset
|
195 new_cacheable_directories: |
48205
320de901896a
dirstate-v2: Truncate directory mtimes to 31 bits of seconds
Simon Sapin <simon.sapin@octobus.net>
parents:
48204
diff
changeset
|
196 Mutex<Vec<(Cow<'on_disk, HgPath>, TruncatedTimestamp)>>, |
49546
ecf9788cd9c4
rust-status: fix typos and add docstrings to dircache related fields
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49524
diff
changeset
|
197 /// Used to invalidate the readdir cache of directories |
ecf9788cd9c4
rust-status: fix typos and add docstrings to dircache related fields
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49524
diff
changeset
|
198 outdated_cached_directories: Mutex<Vec<Cow<'on_disk, HgPath>>>, |
47415
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47356
diff
changeset
|
199 |
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47356
diff
changeset
|
200 /// Whether ignore files like `.hgignore` have changed since the previous |
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47356
diff
changeset
|
201 /// time a `status()` call wrote their hash to the dirstate. `None` means |
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47356
diff
changeset
|
202 /// we don’t know as this run doesn’t list either ignored or uknown files |
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47356
diff
changeset
|
203 /// and therefore isn’t reading `.hgignore`. |
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47356
diff
changeset
|
204 ignore_patterns_have_changed: Option<bool>, |
47355
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
205 |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
206 /// The current time at the start of the `status()` algorithm, as measured |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
207 /// and possibly truncated by the filesystem. |
48538
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
208 filesystem_time_at_status_start: Option<TruncatedTimestamp>, |
47126
d5956136d19d
dirstate-tree: Give to `status()` mutable access to the `DirstateMap`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
209 } |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
210 |
48493
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
211 enum Outcome { |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
212 Modified, |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
213 Added, |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
214 Removed, |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
215 Deleted, |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
216 Clean, |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
217 Ignored, |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
218 Unknown, |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
219 Unsure, |
47126
d5956136d19d
dirstate-tree: Give to `status()` mutable access to the `DirstateMap`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
220 } |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
221 |
49524
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
222 /// Lazy computation of whether a given path has a hgignored |
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
223 /// ancestor. |
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
224 struct HasIgnoredAncestor<'a> { |
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
225 /// `path` and `parent` constitute the inputs to the computation, |
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
226 /// `cache` stores the outcome. |
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
227 path: &'a HgPath, |
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
228 parent: Option<&'a HasIgnoredAncestor<'a>>, |
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
229 cache: OnceCell<bool>, |
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
230 } |
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
231 |
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
232 impl<'a> HasIgnoredAncestor<'a> { |
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
233 fn create( |
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
234 parent: Option<&'a HasIgnoredAncestor<'a>>, |
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
235 path: &'a HgPath, |
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
236 ) -> HasIgnoredAncestor<'a> { |
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
237 Self { |
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
238 path, |
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
239 parent, |
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
240 cache: OnceCell::new(), |
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
241 } |
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
242 } |
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
243 |
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
244 fn force<'b>(&self, ignore_fn: &IgnoreFnType<'b>) -> bool { |
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
245 match self.parent { |
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
246 None => false, |
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
247 Some(parent) => { |
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
248 *(parent.cache.get_or_init(|| { |
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
249 parent.force(ignore_fn) || ignore_fn(&self.path) |
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
250 })) |
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
251 } |
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
252 } |
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
253 } |
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
254 } |
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
255 |
47353
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47352
diff
changeset
|
256 impl<'a, 'tree, 'on_disk> StatusCommon<'a, 'tree, 'on_disk> { |
48493
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
257 fn push_outcome( |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
258 &self, |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
259 which: Outcome, |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
260 dirstate_node: &NodeRef<'tree, 'on_disk>, |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
261 ) -> Result<(), DirstateV2ParseError> { |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
262 let path = dirstate_node |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
263 .full_path_borrowed(self.dmap.on_disk)? |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
264 .detach_from_tree(); |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
265 let copy_source = if self.options.list_copies { |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
266 dirstate_node |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
267 .copy_source_borrowed(self.dmap.on_disk)? |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
268 .map(|source| source.detach_from_tree()) |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
269 } else { |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
270 None |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
271 }; |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
272 self.push_outcome_common(which, path, copy_source); |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
273 Ok(()) |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
274 } |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
275 |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
276 fn push_outcome_without_copy_source( |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
277 &self, |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
278 which: Outcome, |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
279 path: &BorrowedPath<'_, 'on_disk>, |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
280 ) { |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
281 self.push_outcome_common(which, path.detach_from_tree(), None) |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
282 } |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
283 |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
284 fn push_outcome_common( |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
285 &self, |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
286 which: Outcome, |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
287 path: HgPathCow<'on_disk>, |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
288 copy_source: Option<HgPathCow<'on_disk>>, |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
289 ) { |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
290 let mut outcome = self.outcome.lock().unwrap(); |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
291 let vec = match which { |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
292 Outcome::Modified => &mut outcome.modified, |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
293 Outcome::Added => &mut outcome.added, |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
294 Outcome::Removed => &mut outcome.removed, |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
295 Outcome::Deleted => &mut outcome.deleted, |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
296 Outcome::Clean => &mut outcome.clean, |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
297 Outcome::Ignored => &mut outcome.ignored, |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
298 Outcome::Unknown => &mut outcome.unknown, |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
299 Outcome::Unsure => &mut outcome.unsure, |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
300 }; |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
301 vec.push(StatusPath { path, copy_source }); |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
302 } |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
303 |
47129
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47128
diff
changeset
|
304 fn read_dir( |
47131
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47129
diff
changeset
|
305 &self, |
47129
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47128
diff
changeset
|
306 hg_path: &HgPath, |
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47128
diff
changeset
|
307 fs_path: &Path, |
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47128
diff
changeset
|
308 is_at_repo_root: bool, |
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47128
diff
changeset
|
309 ) -> Result<Vec<DirEntry>, ()> { |
47346
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47344
diff
changeset
|
310 DirEntry::read_dir(fs_path, is_at_repo_root) |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47344
diff
changeset
|
311 .map_err(|error| self.io_error(error, hg_path)) |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47344
diff
changeset
|
312 } |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47344
diff
changeset
|
313 |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47344
diff
changeset
|
314 fn io_error(&self, error: std::io::Error, hg_path: &HgPath) { |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47344
diff
changeset
|
315 let errno = error.raw_os_error().expect("expected real OS error"); |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47344
diff
changeset
|
316 self.outcome |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47344
diff
changeset
|
317 .lock() |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47344
diff
changeset
|
318 .unwrap() |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47344
diff
changeset
|
319 .bad |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47344
diff
changeset
|
320 .push((hg_path.to_owned().into(), BadMatch::OsError(errno))) |
47129
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47128
diff
changeset
|
321 } |
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47128
diff
changeset
|
322 |
47479
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47415
diff
changeset
|
323 fn check_for_outdated_directory_cache( |
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47415
diff
changeset
|
324 &self, |
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47415
diff
changeset
|
325 dirstate_node: &NodeRef<'tree, 'on_disk>, |
49547
8ee3889bab92
rust-status: save new dircache even if just invalidated
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49546
diff
changeset
|
326 ) -> Result<bool, DirstateV2ParseError> { |
47479
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47415
diff
changeset
|
327 if self.ignore_patterns_have_changed == Some(true) |
48205
320de901896a
dirstate-v2: Truncate directory mtimes to 31 bits of seconds
Simon Sapin <simon.sapin@octobus.net>
parents:
48204
diff
changeset
|
328 && dirstate_node.cached_directory_mtime()?.is_some() |
47479
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47415
diff
changeset
|
329 { |
49546
ecf9788cd9c4
rust-status: fix typos and add docstrings to dircache related fields
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49524
diff
changeset
|
330 self.outdated_cached_directories.lock().unwrap().push( |
47479
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47415
diff
changeset
|
331 dirstate_node |
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47415
diff
changeset
|
332 .full_path_borrowed(self.dmap.on_disk)? |
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47415
diff
changeset
|
333 .detach_from_tree(), |
49547
8ee3889bab92
rust-status: save new dircache even if just invalidated
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49546
diff
changeset
|
334 ); |
8ee3889bab92
rust-status: save new dircache even if just invalidated
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49546
diff
changeset
|
335 return Ok(true); |
47479
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47415
diff
changeset
|
336 } |
49547
8ee3889bab92
rust-status: save new dircache even if just invalidated
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49546
diff
changeset
|
337 Ok(false) |
47479
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47415
diff
changeset
|
338 } |
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47415
diff
changeset
|
339 |
47355
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
340 /// If this returns true, we can get accurate results by only using |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
341 /// `symlink_metadata` for child nodes that exist in the dirstate and don’t |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
342 /// need to call `read_dir`. |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
343 fn can_skip_fs_readdir( |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
344 &self, |
49718
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
345 directory_entry: &DirEntry, |
48205
320de901896a
dirstate-v2: Truncate directory mtimes to 31 bits of seconds
Simon Sapin <simon.sapin@octobus.net>
parents:
48204
diff
changeset
|
346 cached_directory_mtime: Option<TruncatedTimestamp>, |
47355
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
347 ) -> bool { |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
348 if !self.options.list_unknown && !self.options.list_ignored { |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
349 // All states that we care about listing have corresponding |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
350 // dirstate entries. |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
351 // This happens for example with `hg status -mard`. |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
352 return true; |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
353 } |
47480
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
354 if !self.options.list_ignored |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
355 && self.ignore_patterns_have_changed == Some(false) |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
356 { |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
357 if let Some(cached_mtime) = cached_directory_mtime { |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
358 // The dirstate contains a cached mtime for this directory, set |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
359 // by a previous run of the `status` algorithm which found this |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
360 // directory eligible for `read_dir` caching. |
49718
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
361 if let Ok(meta) = directory_entry.symlink_metadata() { |
48230
15dedc0c5c35
status: Extract TruncatedTimestamp from fs::Metadata without SystemTime
Simon Sapin <simon.sapin@octobus.net>
parents:
48205
diff
changeset
|
362 if cached_mtime |
49718
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
363 .likely_equal_to_mtime_of(&meta) |
48230
15dedc0c5c35
status: Extract TruncatedTimestamp from fs::Metadata without SystemTime
Simon Sapin <simon.sapin@octobus.net>
parents:
48205
diff
changeset
|
364 .unwrap_or(false) |
15dedc0c5c35
status: Extract TruncatedTimestamp from fs::Metadata without SystemTime
Simon Sapin <simon.sapin@octobus.net>
parents:
48205
diff
changeset
|
365 { |
15dedc0c5c35
status: Extract TruncatedTimestamp from fs::Metadata without SystemTime
Simon Sapin <simon.sapin@octobus.net>
parents:
48205
diff
changeset
|
366 // The mtime of that directory has not changed |
15dedc0c5c35
status: Extract TruncatedTimestamp from fs::Metadata without SystemTime
Simon Sapin <simon.sapin@octobus.net>
parents:
48205
diff
changeset
|
367 // since then, which means that the results of |
15dedc0c5c35
status: Extract TruncatedTimestamp from fs::Metadata without SystemTime
Simon Sapin <simon.sapin@octobus.net>
parents:
48205
diff
changeset
|
368 // `read_dir` should also be unchanged. |
15dedc0c5c35
status: Extract TruncatedTimestamp from fs::Metadata without SystemTime
Simon Sapin <simon.sapin@octobus.net>
parents:
48205
diff
changeset
|
369 return true; |
47355
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
370 } |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
371 } |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
372 } |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
373 } |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
374 false |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
375 } |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
376 |
47480
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
377 /// Returns whether all child entries of the filesystem directory have a |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
378 /// corresponding dirstate node or are ignored. |
49524
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
379 fn traverse_fs_directory_and_dirstate<'ancestor>( |
47131
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47129
diff
changeset
|
380 &self, |
49524
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
381 has_ignored_ancestor: &'ancestor HasIgnoredAncestor<'ancestor>, |
47353
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47352
diff
changeset
|
382 dirstate_nodes: ChildNodesRef<'tree, 'on_disk>, |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47352
diff
changeset
|
383 directory_hg_path: &BorrowedPath<'tree, 'on_disk>, |
49718
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
384 directory_entry: &DirEntry, |
48205
320de901896a
dirstate-v2: Truncate directory mtimes to 31 bits of seconds
Simon Sapin <simon.sapin@octobus.net>
parents:
48204
diff
changeset
|
385 cached_directory_mtime: Option<TruncatedTimestamp>, |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
386 is_at_repo_root: bool, |
47355
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
387 ) -> Result<bool, DirstateV2ParseError> { |
49718
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
388 if self.can_skip_fs_readdir(directory_entry, cached_directory_mtime) { |
47355
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
389 dirstate_nodes |
47346
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47344
diff
changeset
|
390 .par_iter() |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47344
diff
changeset
|
391 .map(|dirstate_node| { |
49718
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
392 let fs_path = &directory_entry.fs_path; |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
393 let fs_path = fs_path.join(get_path_from_bytes( |
47346
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47344
diff
changeset
|
394 dirstate_node.base_name(self.dmap.on_disk)?.as_bytes(), |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47344
diff
changeset
|
395 )); |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47344
diff
changeset
|
396 match std::fs::symlink_metadata(&fs_path) { |
49718
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
397 Ok(fs_metadata) => { |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
398 let file_type = |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
399 match fs_metadata.file_type().try_into() { |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
400 Ok(file_type) => file_type, |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
401 Err(_) => return Ok(()), |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
402 }; |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
403 let entry = DirEntry { |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
404 hg_path: Cow::Borrowed( |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
405 dirstate_node |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
406 .full_path(&self.dmap.on_disk)?, |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
407 ), |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
408 fs_path: Cow::Borrowed(&fs_path), |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
409 symlink_metadata: Some(fs_metadata), |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
410 file_type, |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
411 }; |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
412 self.traverse_fs_and_dirstate( |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
413 &entry, |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
414 dirstate_node, |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
415 has_ignored_ancestor, |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
416 ) |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
417 } |
47346
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47344
diff
changeset
|
418 Err(e) if e.kind() == std::io::ErrorKind::NotFound => { |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47344
diff
changeset
|
419 self.traverse_dirstate_only(dirstate_node) |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47344
diff
changeset
|
420 } |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47344
diff
changeset
|
421 Err(error) => { |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47344
diff
changeset
|
422 let hg_path = |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47344
diff
changeset
|
423 dirstate_node.full_path(self.dmap.on_disk)?; |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47344
diff
changeset
|
424 Ok(self.io_error(error, hg_path)) |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47344
diff
changeset
|
425 } |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47344
diff
changeset
|
426 } |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47344
diff
changeset
|
427 }) |
47355
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
428 .collect::<Result<_, _>>()?; |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
429 |
47480
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
430 // We don’t know, so conservatively say this isn’t the case |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
431 let children_all_have_dirstate_node_or_are_ignored = false; |
47355
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
432 |
47480
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
433 return Ok(children_all_have_dirstate_node_or_are_ignored); |
47346
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47344
diff
changeset
|
434 } |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47344
diff
changeset
|
435 |
47129
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47128
diff
changeset
|
436 let mut fs_entries = if let Ok(entries) = self.read_dir( |
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47128
diff
changeset
|
437 directory_hg_path, |
49718
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
438 &directory_entry.fs_path, |
47129
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47128
diff
changeset
|
439 is_at_repo_root, |
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47128
diff
changeset
|
440 ) { |
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47128
diff
changeset
|
441 entries |
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47128
diff
changeset
|
442 } else { |
47352
5e12b6bfdd3e
dirstate-tree: Fix status algorithm with unreadable directory
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
443 // Treat an unreadable directory (typically because of insufficient |
5e12b6bfdd3e
dirstate-tree: Fix status algorithm with unreadable directory
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
444 // permissions) like an empty directory. `self.read_dir` has |
5e12b6bfdd3e
dirstate-tree: Fix status algorithm with unreadable directory
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
445 // already called `self.io_error` so a warning will be emitted. |
5e12b6bfdd3e
dirstate-tree: Fix status algorithm with unreadable directory
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
446 Vec::new() |
47129
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47128
diff
changeset
|
447 }; |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
448 |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
449 // `merge_join_by` requires both its input iterators to be sorted: |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
450 |
47341
69530e5d4fe5
dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents:
47339
diff
changeset
|
451 let dirstate_nodes = dirstate_nodes.sorted(); |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
452 // `sort_unstable_by_key` doesn’t allow keys borrowing from the value: |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
453 // https://github.com/rust-lang/rust/issues/34162 |
49717
6b32d39e9a67
rust-status: make `DirEntry` attributes clearer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49524
diff
changeset
|
454 fs_entries.sort_unstable_by(|e1, e2| e1.hg_path.cmp(&e2.hg_path)); |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
455 |
47343
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47341
diff
changeset
|
456 // Propagate here any error that would happen inside the comparison |
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47341
diff
changeset
|
457 // callback below |
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47341
diff
changeset
|
458 for dirstate_node in &dirstate_nodes { |
47344
8d0260d0dbc9
dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents:
47343
diff
changeset
|
459 dirstate_node.base_name(self.dmap.on_disk)?; |
47343
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47341
diff
changeset
|
460 } |
47131
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47129
diff
changeset
|
461 itertools::merge_join_by( |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
462 dirstate_nodes, |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
463 &fs_entries, |
47341
69530e5d4fe5
dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents:
47339
diff
changeset
|
464 |dirstate_node, fs_entry| { |
47343
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47341
diff
changeset
|
465 // This `unwrap` never panics because we already propagated |
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47341
diff
changeset
|
466 // those errors above |
47344
8d0260d0dbc9
dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents:
47343
diff
changeset
|
467 dirstate_node |
8d0260d0dbc9
dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents:
47343
diff
changeset
|
468 .base_name(self.dmap.on_disk) |
8d0260d0dbc9
dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents:
47343
diff
changeset
|
469 .unwrap() |
49717
6b32d39e9a67
rust-status: make `DirEntry` attributes clearer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49524
diff
changeset
|
470 .cmp(&fs_entry.hg_path) |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
471 }, |
47131
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47129
diff
changeset
|
472 ) |
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47129
diff
changeset
|
473 .par_bridge() |
47343
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47341
diff
changeset
|
474 .map(|pair| { |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
475 use itertools::EitherOrBoth::*; |
47480
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
476 let has_dirstate_node_or_is_ignored; |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
477 match pair { |
47480
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
478 Both(dirstate_node, fs_entry) => { |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
479 self.traverse_fs_and_dirstate( |
49718
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
480 &fs_entry, |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
481 dirstate_node, |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
482 has_ignored_ancestor, |
47480
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
483 )?; |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
484 has_dirstate_node_or_is_ignored = true |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
485 } |
47341
69530e5d4fe5
dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents:
47339
diff
changeset
|
486 Left(dirstate_node) => { |
47480
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
487 self.traverse_dirstate_only(dirstate_node)?; |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
488 has_dirstate_node_or_is_ignored = true; |
47341
69530e5d4fe5
dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents:
47339
diff
changeset
|
489 } |
47480
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
490 Right(fs_entry) => { |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
491 has_dirstate_node_or_is_ignored = self.traverse_fs_only( |
49524
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
492 has_ignored_ancestor.force(&self.ignore_fn), |
47480
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
493 directory_hg_path, |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
494 fs_entry, |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
495 ) |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
496 } |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
497 } |
47480
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
498 Ok(has_dirstate_node_or_is_ignored) |
47131
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47129
diff
changeset
|
499 }) |
47480
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
500 .try_reduce(|| true, |a, b| Ok(a && b)) |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
501 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
502 |
49524
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
503 fn traverse_fs_and_dirstate<'ancestor>( |
47131
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47129
diff
changeset
|
504 &self, |
49718
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
505 fs_entry: &DirEntry, |
47353
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47352
diff
changeset
|
506 dirstate_node: NodeRef<'tree, 'on_disk>, |
49524
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
507 has_ignored_ancestor: &'ancestor HasIgnoredAncestor<'ancestor>, |
47343
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47341
diff
changeset
|
508 ) -> Result<(), DirstateV2ParseError> { |
49547
8ee3889bab92
rust-status: save new dircache even if just invalidated
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49546
diff
changeset
|
509 let outdated_dircache = |
8ee3889bab92
rust-status: save new dircache even if just invalidated
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49546
diff
changeset
|
510 self.check_for_outdated_directory_cache(&dirstate_node)?; |
47353
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47352
diff
changeset
|
511 let hg_path = &dirstate_node.full_path_borrowed(self.dmap.on_disk)?; |
49718
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
512 let file_or_symlink = fs_entry.is_file() || fs_entry.is_symlink(); |
47128
aeb03758f37a
dirstate-tree: Ignore FIFOs etc. in the status algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47127
diff
changeset
|
513 if !file_or_symlink { |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
514 // If we previously had a file here, it was removed (with |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
515 // `hg rm` or similar) or deleted before it could be |
47128
aeb03758f37a
dirstate-tree: Ignore FIFOs etc. in the status algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47127
diff
changeset
|
516 // replaced by a directory or something else. |
48493
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
517 self.mark_removed_or_deleted_if_file(&dirstate_node)?; |
47128
aeb03758f37a
dirstate-tree: Ignore FIFOs etc. in the status algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47127
diff
changeset
|
518 } |
49718
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
519 if fs_entry.is_dir() { |
47128
aeb03758f37a
dirstate-tree: Ignore FIFOs etc. in the status algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47127
diff
changeset
|
520 if self.options.collect_traversed_dirs { |
47353
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47352
diff
changeset
|
521 self.outcome |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47352
diff
changeset
|
522 .lock() |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47352
diff
changeset
|
523 .unwrap() |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47352
diff
changeset
|
524 .traversed |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47352
diff
changeset
|
525 .push(hg_path.detach_from_tree()) |
47128
aeb03758f37a
dirstate-tree: Ignore FIFOs etc. in the status algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47127
diff
changeset
|
526 } |
49524
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
527 let is_ignored = HasIgnoredAncestor::create( |
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
528 Some(&has_ignored_ancestor), |
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
529 hg_path, |
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
530 ); |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
531 let is_at_repo_root = false; |
47480
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
532 let children_all_have_dirstate_node_or_are_ignored = self |
47355
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
533 .traverse_fs_directory_and_dirstate( |
49524
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
534 &is_ignored, |
47355
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
535 dirstate_node.children(self.dmap.on_disk)?, |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
536 hg_path, |
49718
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
537 fs_entry, |
48205
320de901896a
dirstate-v2: Truncate directory mtimes to 31 bits of seconds
Simon Sapin <simon.sapin@octobus.net>
parents:
48204
diff
changeset
|
538 dirstate_node.cached_directory_mtime()?, |
47355
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
539 is_at_repo_root, |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
540 )?; |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
541 self.maybe_save_directory_mtime( |
47480
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
542 children_all_have_dirstate_node_or_are_ignored, |
49718
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
543 fs_entry, |
47355
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
544 dirstate_node, |
49547
8ee3889bab92
rust-status: save new dircache even if just invalidated
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49546
diff
changeset
|
545 outdated_dircache, |
47343
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47341
diff
changeset
|
546 )? |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
547 } else { |
49524
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
548 if file_or_symlink && self.matcher.matches(&hg_path) { |
49197
c4ccd0346f5c
rust-status: stop using `state()` in the dispatch logic
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49196
diff
changeset
|
549 if let Some(entry) = dirstate_node.entry()? { |
c4ccd0346f5c
rust-status: stop using `state()` in the dispatch logic
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49196
diff
changeset
|
550 if !entry.any_tracked() { |
c4ccd0346f5c
rust-status: stop using `state()` in the dispatch logic
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49196
diff
changeset
|
551 // Forward-compat if we start tracking unknown/ignored |
c4ccd0346f5c
rust-status: stop using `state()` in the dispatch logic
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49196
diff
changeset
|
552 // files for caching reasons |
c4ccd0346f5c
rust-status: stop using `state()` in the dispatch logic
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49196
diff
changeset
|
553 self.mark_unknown_or_ignored( |
49524
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
554 has_ignored_ancestor.force(&self.ignore_fn), |
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
555 &hg_path, |
49197
c4ccd0346f5c
rust-status: stop using `state()` in the dispatch logic
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49196
diff
changeset
|
556 ); |
c4ccd0346f5c
rust-status: stop using `state()` in the dispatch logic
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49196
diff
changeset
|
557 } |
c4ccd0346f5c
rust-status: stop using `state()` in the dispatch logic
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49196
diff
changeset
|
558 if entry.added() { |
c4ccd0346f5c
rust-status: stop using `state()` in the dispatch logic
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49196
diff
changeset
|
559 self.push_outcome(Outcome::Added, &dirstate_node)?; |
c4ccd0346f5c
rust-status: stop using `state()` in the dispatch logic
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49196
diff
changeset
|
560 } else if entry.removed() { |
c4ccd0346f5c
rust-status: stop using `state()` in the dispatch logic
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49196
diff
changeset
|
561 self.push_outcome(Outcome::Removed, &dirstate_node)?; |
c4ccd0346f5c
rust-status: stop using `state()` in the dispatch logic
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49196
diff
changeset
|
562 } else if entry.modified() { |
c4ccd0346f5c
rust-status: stop using `state()` in the dispatch logic
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49196
diff
changeset
|
563 self.push_outcome(Outcome::Modified, &dirstate_node)?; |
c4ccd0346f5c
rust-status: stop using `state()` in the dispatch logic
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49196
diff
changeset
|
564 } else { |
49718
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
565 self.handle_normal_file(&dirstate_node, fs_entry)?; |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
566 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
567 } else { |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
568 // `node.entry.is_none()` indicates a "directory" |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
569 // node, but the filesystem has a file |
47480
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
570 self.mark_unknown_or_ignored( |
49524
eb02decdf0ab
dirstate-v2: skip evaluation of hgignore regex on cached directories
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49400
diff
changeset
|
571 has_ignored_ancestor.force(&self.ignore_fn), |
47480
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
572 hg_path, |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
573 ); |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
574 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
575 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
576 |
47344
8d0260d0dbc9
dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents:
47343
diff
changeset
|
577 for child_node in dirstate_node.children(self.dmap.on_disk)?.iter() |
8d0260d0dbc9
dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents:
47343
diff
changeset
|
578 { |
47343
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47341
diff
changeset
|
579 self.traverse_dirstate_only(child_node)? |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
580 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
581 } |
47343
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47341
diff
changeset
|
582 Ok(()) |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
583 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
584 |
49547
8ee3889bab92
rust-status: save new dircache even if just invalidated
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49546
diff
changeset
|
585 /// Save directory mtime if applicable. |
8ee3889bab92
rust-status: save new dircache even if just invalidated
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49546
diff
changeset
|
586 /// |
8ee3889bab92
rust-status: save new dircache even if just invalidated
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49546
diff
changeset
|
587 /// `outdated_directory_cache` is `true` if we've just invalidated the |
8ee3889bab92
rust-status: save new dircache even if just invalidated
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49546
diff
changeset
|
588 /// cache for this directory in `check_for_outdated_directory_cache`, |
8ee3889bab92
rust-status: save new dircache even if just invalidated
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49546
diff
changeset
|
589 /// which forces the update. |
47355
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
590 fn maybe_save_directory_mtime( |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
591 &self, |
47480
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
592 children_all_have_dirstate_node_or_are_ignored: bool, |
49718
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
593 directory_entry: &DirEntry, |
47355
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
594 dirstate_node: NodeRef<'tree, 'on_disk>, |
49547
8ee3889bab92
rust-status: save new dircache even if just invalidated
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49546
diff
changeset
|
595 outdated_directory_cache: bool, |
47355
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
596 ) -> Result<(), DirstateV2ParseError> { |
48538
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
597 if !children_all_have_dirstate_node_or_are_ignored { |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
598 return Ok(()); |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
599 } |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
600 // All filesystem directory entries from `read_dir` have a |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
601 // corresponding node in the dirstate, so we can reconstitute the |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
602 // names of those entries without calling `read_dir` again. |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
603 |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
604 // TODO: use let-else here and below when available: |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
605 // https://github.com/rust-lang/rust/issues/87335 |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
606 let status_start = if let Some(status_start) = |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
607 &self.filesystem_time_at_status_start |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
608 { |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
609 status_start |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
610 } else { |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
611 return Ok(()); |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
612 }; |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
613 |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
614 // Although the Rust standard library’s `SystemTime` type |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
615 // has nanosecond precision, the times reported for a |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
616 // directory’s (or file’s) modified time may have lower |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
617 // resolution based on the filesystem (for example ext3 |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
618 // only stores integer seconds), kernel (see |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
619 // https://stackoverflow.com/a/14393315/1162888), etc. |
49718
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
620 let metadata = match directory_entry.symlink_metadata() { |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
621 Ok(meta) => meta, |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
622 Err(_) => return Ok(()), |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
623 }; |
48538
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
624 let directory_mtime = if let Ok(option) = |
49718
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
625 TruncatedTimestamp::for_reliable_mtime_of(&metadata, status_start) |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
626 { |
48538
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
627 if let Some(directory_mtime) = option { |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
628 directory_mtime |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
629 } else { |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
630 // The directory was modified too recently, |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
631 // don’t cache its `read_dir` results. |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
632 // |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
633 // 1. A change to this directory (direct child was |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
634 // added or removed) cause its mtime to be set |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
635 // (possibly truncated) to `directory_mtime` |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
636 // 2. This `status` algorithm calls `read_dir` |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
637 // 3. An other change is made to the same directory is |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
638 // made so that calling `read_dir` agin would give |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
639 // different results, but soon enough after 1. that |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
640 // the mtime stays the same |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
641 // |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
642 // On a system where the time resolution poor, this |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
643 // scenario is not unlikely if all three steps are caused |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
644 // by the same script. |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
645 return Ok(()); |
47355
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
646 } |
48538
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
647 } else { |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
648 // OS/libc does not support mtime? |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
649 return Ok(()); |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
650 }; |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
651 // We’ve observed (through `status_start`) that time has |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
652 // “progressed” since `directory_mtime`, so any further |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
653 // change to this directory is extremely likely to cause a |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
654 // different mtime. |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
655 // |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
656 // Having the same mtime again is not entirely impossible |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
657 // since the system clock is not monotonous. It could jump |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
658 // backward to some point before `directory_mtime`, then a |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
659 // directory change could potentially happen during exactly |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
660 // the wrong tick. |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
661 // |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
662 // We deem this scenario (unlike the previous one) to be |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
663 // unlikely enough in practice. |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
664 |
49547
8ee3889bab92
rust-status: save new dircache even if just invalidated
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49546
diff
changeset
|
665 let is_up_to_date = if let Some(cached) = |
8ee3889bab92
rust-status: save new dircache even if just invalidated
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49546
diff
changeset
|
666 dirstate_node.cached_directory_mtime()? |
8ee3889bab92
rust-status: save new dircache even if just invalidated
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49546
diff
changeset
|
667 { |
8ee3889bab92
rust-status: save new dircache even if just invalidated
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49546
diff
changeset
|
668 !outdated_directory_cache && cached.likely_equal(directory_mtime) |
8ee3889bab92
rust-status: save new dircache even if just invalidated
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49546
diff
changeset
|
669 } else { |
8ee3889bab92
rust-status: save new dircache even if just invalidated
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49546
diff
changeset
|
670 false |
8ee3889bab92
rust-status: save new dircache even if just invalidated
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49546
diff
changeset
|
671 }; |
48538
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
672 if !is_up_to_date { |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
673 let hg_path = dirstate_node |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
674 .full_path_borrowed(self.dmap.on_disk)? |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
675 .detach_from_tree(); |
49546
ecf9788cd9c4
rust-status: fix typos and add docstrings to dircache related fields
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49524
diff
changeset
|
676 self.new_cacheable_directories |
48538
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
677 .lock() |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
678 .unwrap() |
4afb9627dc77
dirstate-v2: Apply SECOND_AMBIGUOUS to directory mtimes too
Simon Sapin <simon.sapin@octobus.net>
parents:
48493
diff
changeset
|
679 .push((hg_path, directory_mtime)) |
47355
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
680 } |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
681 Ok(()) |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
682 } |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
683 |
49197
c4ccd0346f5c
rust-status: stop using `state()` in the dispatch logic
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49196
diff
changeset
|
684 /// A file that is clean in the dirstate was found in the filesystem |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
685 fn handle_normal_file( |
47131
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47129
diff
changeset
|
686 &self, |
47353
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47352
diff
changeset
|
687 dirstate_node: &NodeRef<'tree, 'on_disk>, |
49718
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
688 fs_entry: &DirEntry, |
47343
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47341
diff
changeset
|
689 ) -> Result<(), DirstateV2ParseError> { |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
690 // Keep the low 31 bits |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
691 fn truncate_u64(value: u64) -> i32 { |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
692 (value & 0x7FFF_FFFF) as i32 |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
693 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
694 |
49718
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
695 let fs_metadata = match fs_entry.symlink_metadata() { |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
696 Ok(meta) => meta, |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
697 Err(_) => return Ok(()), |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
698 }; |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
699 |
47341
69530e5d4fe5
dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents:
47339
diff
changeset
|
700 let entry = dirstate_node |
47343
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47341
diff
changeset
|
701 .entry()? |
47341
69530e5d4fe5
dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents:
47339
diff
changeset
|
702 .expect("handle_normal_file called with entry-less node"); |
47346
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47344
diff
changeset
|
703 let mode_changed = |
49718
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
704 || self.options.check_exec && entry.mode_changed(&fs_metadata); |
48044
f2a9db29cb2d
rust: Make the fields of DirstateEntry private
Simon Sapin <simon.sapin@octobus.net>
parents:
47480
diff
changeset
|
705 let size = entry.size(); |
f2a9db29cb2d
rust: Make the fields of DirstateEntry private
Simon Sapin <simon.sapin@octobus.net>
parents:
47480
diff
changeset
|
706 let size_changed = size != truncate_u64(fs_metadata.len()); |
f2a9db29cb2d
rust: Make the fields of DirstateEntry private
Simon Sapin <simon.sapin@octobus.net>
parents:
47480
diff
changeset
|
707 if size >= 0 && size_changed && fs_metadata.file_type().is_symlink() { |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
708 // issue6456: Size returned may be longer due to encryption |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
709 // on EXT-4 fscrypt. TODO maybe only do it on EXT4? |
48493
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
710 self.push_outcome(Outcome::Unsure, dirstate_node)? |
47343
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47341
diff
changeset
|
711 } else if dirstate_node.has_copy_source() |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
712 || entry.is_from_other_parent() |
48044
f2a9db29cb2d
rust: Make the fields of DirstateEntry private
Simon Sapin <simon.sapin@octobus.net>
parents:
47480
diff
changeset
|
713 || (size >= 0 && (size_changed || mode_changed())) |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
714 { |
48493
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
715 self.push_outcome(Outcome::Modified, dirstate_node)? |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
716 } else { |
48271
269ff8978086
dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
48268
diff
changeset
|
717 let mtime_looks_clean; |
269ff8978086
dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
48268
diff
changeset
|
718 if let Some(dirstate_mtime) = entry.truncated_mtime() { |
49718
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
719 let fs_mtime = TruncatedTimestamp::for_mtime_of(&fs_metadata) |
48274
83d0bd45b662
dirstate-v2: actually use sub-second mtime precision
Simon Sapin <simon.sapin@octobus.net>
parents:
48271
diff
changeset
|
720 .expect("OS/libc does not support mtime?"); |
48439
b80e5e75d51e
dirstate: remove `lastnormaltime` mechanism
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
48274
diff
changeset
|
721 // There might be a change in the future if for example the |
b80e5e75d51e
dirstate: remove `lastnormaltime` mechanism
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
48274
diff
changeset
|
722 // internal clock become off while process run, but this is a |
b80e5e75d51e
dirstate: remove `lastnormaltime` mechanism
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
48274
diff
changeset
|
723 // case where the issues the user would face |
b80e5e75d51e
dirstate: remove `lastnormaltime` mechanism
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
48274
diff
changeset
|
724 // would be a lot worse and there is nothing we |
b80e5e75d51e
dirstate: remove `lastnormaltime` mechanism
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
48274
diff
changeset
|
725 // can really do. |
48271
269ff8978086
dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
48268
diff
changeset
|
726 mtime_looks_clean = fs_mtime.likely_equal(dirstate_mtime) |
269ff8978086
dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
48268
diff
changeset
|
727 } else { |
269ff8978086
dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
48268
diff
changeset
|
728 // No mtime in the dirstate entry |
269ff8978086
dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
48268
diff
changeset
|
729 mtime_looks_clean = false |
269ff8978086
dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
48268
diff
changeset
|
730 }; |
269ff8978086
dirstate: store mtimes with nanosecond precision in memory
Simon Sapin <simon.sapin@octobus.net>
parents:
48268
diff
changeset
|
731 if !mtime_looks_clean { |
48493
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
732 self.push_outcome(Outcome::Unsure, dirstate_node)? |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
733 } else if self.options.list_clean { |
48493
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
734 self.push_outcome(Outcome::Clean, dirstate_node)? |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
735 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
736 } |
47343
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47341
diff
changeset
|
737 Ok(()) |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
738 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
739 |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
740 /// A node in the dirstate tree has no corresponding filesystem entry |
47343
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47341
diff
changeset
|
741 fn traverse_dirstate_only( |
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47341
diff
changeset
|
742 &self, |
47353
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47352
diff
changeset
|
743 dirstate_node: NodeRef<'tree, 'on_disk>, |
47343
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47341
diff
changeset
|
744 ) -> Result<(), DirstateV2ParseError> { |
47479
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47415
diff
changeset
|
745 self.check_for_outdated_directory_cache(&dirstate_node)?; |
48493
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
746 self.mark_removed_or_deleted_if_file(&dirstate_node)?; |
47341
69530e5d4fe5
dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents:
47339
diff
changeset
|
747 dirstate_node |
47344
8d0260d0dbc9
dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents:
47343
diff
changeset
|
748 .children(self.dmap.on_disk)? |
47341
69530e5d4fe5
dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents:
47339
diff
changeset
|
749 .par_iter() |
47343
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47341
diff
changeset
|
750 .map(|child_node| self.traverse_dirstate_only(child_node)) |
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47341
diff
changeset
|
751 .collect() |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
752 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
753 |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
754 /// A node in the dirstate tree has no corresponding *file* on the |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
755 /// filesystem |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
756 /// |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
757 /// Does nothing on a "directory" node |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
758 fn mark_removed_or_deleted_if_file( |
47131
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47129
diff
changeset
|
759 &self, |
48493
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
760 dirstate_node: &NodeRef<'tree, 'on_disk>, |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
761 ) -> Result<(), DirstateV2ParseError> { |
49196
126d253eb274
rust-status: stop using `state()` in `handle_normal_file`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49183
diff
changeset
|
762 if let Some(entry) = dirstate_node.entry()? { |
126d253eb274
rust-status: stop using `state()` in `handle_normal_file`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49183
diff
changeset
|
763 if !entry.any_tracked() { |
126d253eb274
rust-status: stop using `state()` in `handle_normal_file`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49183
diff
changeset
|
764 // Future-compat for when we start storing ignored and unknown |
126d253eb274
rust-status: stop using `state()` in `handle_normal_file`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49183
diff
changeset
|
765 // files for caching reasons |
126d253eb274
rust-status: stop using `state()` in `handle_normal_file`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49183
diff
changeset
|
766 return Ok(()); |
126d253eb274
rust-status: stop using `state()` in `handle_normal_file`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49183
diff
changeset
|
767 } |
48493
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
768 let path = dirstate_node.full_path(self.dmap.on_disk)?; |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
769 if self.matcher.matches(path) { |
49196
126d253eb274
rust-status: stop using `state()` in `handle_normal_file`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49183
diff
changeset
|
770 if entry.removed() { |
48493
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
771 self.push_outcome(Outcome::Removed, dirstate_node)? |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
772 } else { |
48493
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
773 self.push_outcome(Outcome::Deleted, &dirstate_node)? |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
774 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
775 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
776 } |
48493
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
777 Ok(()) |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
778 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
779 |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
780 /// Something in the filesystem has no corresponding dirstate node |
47480
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
781 /// |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
782 /// Returns whether that path is ignored |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
783 fn traverse_fs_only( |
47131
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47129
diff
changeset
|
784 &self, |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
785 has_ignored_ancestor: bool, |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
786 directory_hg_path: &HgPath, |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
787 fs_entry: &DirEntry, |
47480
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
788 ) -> bool { |
49717
6b32d39e9a67
rust-status: make `DirEntry` attributes clearer
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49524
diff
changeset
|
789 let hg_path = directory_hg_path.join(&fs_entry.hg_path); |
49718
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
790 let file_or_symlink = fs_entry.is_file() || fs_entry.is_symlink(); |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
791 if fs_entry.is_dir() { |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
792 let is_ignored = |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
793 has_ignored_ancestor || (self.ignore_fn)(&hg_path); |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
794 let traverse_children = if is_ignored { |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
795 // Descendants of an ignored directory are all ignored |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
796 self.options.list_ignored |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
797 } else { |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
798 // Descendants of an unknown directory may be either unknown or |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
799 // ignored |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
800 self.options.list_unknown || self.options.list_ignored |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
801 }; |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
802 if traverse_children { |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
803 let is_at_repo_root = false; |
49718
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
804 if let Ok(children_fs_entries) = |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
805 self.read_dir(&hg_path, &fs_entry.fs_path, is_at_repo_root) |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
806 { |
47131
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47129
diff
changeset
|
807 children_fs_entries.par_iter().for_each(|child_fs_entry| { |
47129
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47128
diff
changeset
|
808 self.traverse_fs_only( |
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47128
diff
changeset
|
809 is_ignored, |
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47128
diff
changeset
|
810 &hg_path, |
47131
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47129
diff
changeset
|
811 child_fs_entry, |
47480
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
812 ); |
47131
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47129
diff
changeset
|
813 }) |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
814 } |
49400
7e5377bdb66e
rust-status: ignored directories are now correctly only listed if opted into
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49365
diff
changeset
|
815 if self.options.collect_traversed_dirs { |
7e5377bdb66e
rust-status: ignored directories are now correctly only listed if opted into
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49365
diff
changeset
|
816 self.outcome.lock().unwrap().traversed.push(hg_path.into()) |
7e5377bdb66e
rust-status: ignored directories are now correctly only listed if opted into
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49365
diff
changeset
|
817 } |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
818 } |
47480
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
819 is_ignored |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
820 } else { |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
821 if file_or_symlink { |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
822 if self.matcher.matches(&hg_path) { |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
823 self.mark_unknown_or_ignored( |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
824 has_ignored_ancestor, |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
825 &BorrowedPath::InMemory(&hg_path), |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
826 ) |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
827 } else { |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
828 // We haven’t computed whether this path is ignored. It |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
829 // might not be, and a future run of status might have a |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
830 // different matcher that matches it. So treat it as not |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
831 // ignored. That is, inhibit readdir caching of the parent |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
832 // directory. |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
833 false |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
834 } |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
835 } else { |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
836 // This is neither a directory, a plain file, or a symlink. |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
837 // Treat it like an ignored file. |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
838 true |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
839 } |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
840 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
841 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
842 |
47480
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
843 /// Returns whether that path is ignored |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
844 fn mark_unknown_or_ignored( |
47131
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47129
diff
changeset
|
845 &self, |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
846 has_ignored_ancestor: bool, |
47353
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47352
diff
changeset
|
847 hg_path: &BorrowedPath<'_, 'on_disk>, |
47480
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
848 ) -> bool { |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
849 let is_ignored = has_ignored_ancestor || (self.ignore_fn)(&hg_path); |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
850 if is_ignored { |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
851 if self.options.list_ignored { |
48493
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
852 self.push_outcome_without_copy_source( |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
853 Outcome::Ignored, |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
854 hg_path, |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
855 ) |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
856 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
857 } else { |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
858 if self.options.list_unknown { |
48493
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
859 self.push_outcome_without_copy_source( |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
860 Outcome::Unknown, |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
861 hg_path, |
473af5cbc209
rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents:
48468
diff
changeset
|
862 ) |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
863 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
864 } |
47480
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47479
diff
changeset
|
865 is_ignored |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
866 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
867 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
868 |
49718
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
869 /// Since [`std::fs::FileType`] cannot be built directly, we emulate what we |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
870 /// care about. |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
871 #[derive(Copy, Clone, Debug, PartialEq, Eq)] |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
872 enum FakeFileType { |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
873 File, |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
874 Directory, |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
875 Symlink, |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
876 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
877 |
49718
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
878 impl TryFrom<std::fs::FileType> for FakeFileType { |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
879 type Error = (); |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
880 |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
881 fn try_from(f: std::fs::FileType) -> Result<Self, Self::Error> { |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
882 if f.is_dir() { |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
883 Ok(Self::Directory) |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
884 } else if f.is_file() { |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
885 Ok(Self::File) |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
886 } else if f.is_symlink() { |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
887 Ok(Self::Symlink) |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
888 } else { |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
889 // Things like FIFO etc. |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
890 Err(()) |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
891 } |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
892 } |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
893 } |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
894 |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
895 struct DirEntry<'a> { |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
896 /// Path as stored in the dirstate, or just the filename for optimization. |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
897 hg_path: HgPathCow<'a>, |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
898 /// Filesystem path |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
899 fs_path: Cow<'a, Path>, |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
900 /// Lazily computed |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
901 symlink_metadata: Option<std::fs::Metadata>, |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
902 /// Already computed for ergonomics. |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
903 file_type: FakeFileType, |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
904 } |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
905 |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
906 impl<'a> DirEntry<'a> { |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
907 /// Returns **unsorted** entries in the given directory, with name, |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
908 /// metadata and file type. |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
909 /// |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
910 /// If a `.hg` sub-directory is encountered: |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
911 /// |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
912 /// * At the repository root, ignore that sub-directory |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
913 /// * Elsewhere, we’re listing the content of a sub-repo. Return an empty |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
914 /// list instead. |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
915 fn read_dir(path: &Path, is_at_repo_root: bool) -> io::Result<Vec<Self>> { |
48750
94e36b230990
status: prefer relative paths in Rust code
Simon Sapin <simon.sapin@octobus.net>
parents:
48538
diff
changeset
|
916 // `read_dir` returns a "not found" error for the empty path |
94e36b230990
status: prefer relative paths in Rust code
Simon Sapin <simon.sapin@octobus.net>
parents:
48538
diff
changeset
|
917 let at_cwd = path == Path::new(""); |
94e36b230990
status: prefer relative paths in Rust code
Simon Sapin <simon.sapin@octobus.net>
parents:
48538
diff
changeset
|
918 let read_dir_path = if at_cwd { Path::new(".") } else { path }; |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
919 let mut results = Vec::new(); |
48750
94e36b230990
status: prefer relative paths in Rust code
Simon Sapin <simon.sapin@octobus.net>
parents:
48538
diff
changeset
|
920 for entry in read_dir_path.read_dir()? { |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
921 let entry = entry?; |
49718
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
922 let file_type = match entry.file_type() { |
48378
dcec16e799dd
status: fix hg status race against file deletion
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48274
diff
changeset
|
923 Ok(v) => v, |
dcec16e799dd
status: fix hg status race against file deletion
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48274
diff
changeset
|
924 Err(e) => { |
dcec16e799dd
status: fix hg status race against file deletion
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48274
diff
changeset
|
925 // race with file deletion? |
dcec16e799dd
status: fix hg status race against file deletion
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48274
diff
changeset
|
926 if e.kind() == std::io::ErrorKind::NotFound { |
dcec16e799dd
status: fix hg status race against file deletion
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48274
diff
changeset
|
927 continue; |
dcec16e799dd
status: fix hg status race against file deletion
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48274
diff
changeset
|
928 } else { |
dcec16e799dd
status: fix hg status race against file deletion
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48274
diff
changeset
|
929 return Err(e); |
dcec16e799dd
status: fix hg status race against file deletion
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48274
diff
changeset
|
930 } |
dcec16e799dd
status: fix hg status race against file deletion
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48274
diff
changeset
|
931 } |
dcec16e799dd
status: fix hg status race against file deletion
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48274
diff
changeset
|
932 }; |
48750
94e36b230990
status: prefer relative paths in Rust code
Simon Sapin <simon.sapin@octobus.net>
parents:
48538
diff
changeset
|
933 let file_name = entry.file_name(); |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
934 // FIXME don't do this when cached |
48750
94e36b230990
status: prefer relative paths in Rust code
Simon Sapin <simon.sapin@octobus.net>
parents:
48538
diff
changeset
|
935 if file_name == ".hg" { |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
936 if is_at_repo_root { |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
937 // Skip the repo’s own .hg (might be a symlink) |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
938 continue; |
49718
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
939 } else if file_type.is_dir() { |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
940 // A .hg sub-directory at another location means a subrepo, |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
941 // skip it entirely. |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
942 return Ok(Vec::new()); |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
943 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
944 } |
48750
94e36b230990
status: prefer relative paths in Rust code
Simon Sapin <simon.sapin@octobus.net>
parents:
48538
diff
changeset
|
945 let full_path = if at_cwd { |
94e36b230990
status: prefer relative paths in Rust code
Simon Sapin <simon.sapin@octobus.net>
parents:
48538
diff
changeset
|
946 file_name.clone().into() |
94e36b230990
status: prefer relative paths in Rust code
Simon Sapin <simon.sapin@octobus.net>
parents:
48538
diff
changeset
|
947 } else { |
94e36b230990
status: prefer relative paths in Rust code
Simon Sapin <simon.sapin@octobus.net>
parents:
48538
diff
changeset
|
948 entry.path() |
94e36b230990
status: prefer relative paths in Rust code
Simon Sapin <simon.sapin@octobus.net>
parents:
48538
diff
changeset
|
949 }; |
49718
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
950 let filename = |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
951 Cow::Owned(get_bytes_from_os_string(file_name).into()); |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
952 let file_type = match FakeFileType::try_from(file_type) { |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
953 Ok(file_type) => file_type, |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
954 Err(_) => continue, |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
955 }; |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
956 results.push(DirEntry { |
49718
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
957 hg_path: filename, |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
958 fs_path: Cow::Owned(full_path.to_path_buf()), |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
959 symlink_metadata: None, |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
960 file_type, |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
961 }) |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
962 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
963 Ok(results) |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
964 } |
49718
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
965 |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
966 fn symlink_metadata(&self) -> Result<std::fs::Metadata, std::io::Error> { |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
967 match &self.symlink_metadata { |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
968 Some(meta) => Ok(meta.clone()), |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
969 None => std::fs::symlink_metadata(&self.fs_path), |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
970 } |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
971 } |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
972 |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
973 fn is_dir(&self) -> bool { |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
974 self.file_type == FakeFileType::Directory |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
975 } |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
976 |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
977 fn is_file(&self) -> bool { |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
978 self.file_type == FakeFileType::File |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
979 } |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
980 |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
981 fn is_symlink(&self) -> bool { |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
982 self.file_type == FakeFileType::Symlink |
da48f170d203
rust-status: query fs traversal metadata lazily
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49717
diff
changeset
|
983 } |
47127
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47126
diff
changeset
|
984 } |
47355
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
985 |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
986 /// Return the `mtime` of a temporary file newly-created in the `.hg` directory |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
987 /// of the give repository. |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
988 /// |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
989 /// This is similar to `SystemTime::now()`, with the result truncated to the |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
990 /// same time resolution as other files’ modification times. Using `.hg` |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
991 /// instead of the system’s default temporary directory (such as `/tmp`) makes |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
992 /// it more likely the temporary file is in the same disk partition as contents |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
993 /// of the working directory, which can matter since different filesystems may |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
994 /// store timestamps with different resolutions. |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
995 /// |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
996 /// This may fail, typically if we lack write permissions. In that case we |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
997 /// should continue the `status()` algoritm anyway and consider the current |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
998 /// date/time to be unknown. |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
999 fn filesystem_now(repo_root: &Path) -> Result<SystemTime, io::Error> { |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
1000 tempfile::tempfile_in(repo_root.join(".hg"))? |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
1001 .metadata()? |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
1002 .modified() |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47353
diff
changeset
|
1003 } |