Mercurial > public > mercurial-scm > hg
annotate rust/hg-core/src/dirstate_tree/status.rs @ 47692:e5fb14a07866
dirstate-map: move most of `dirstate.update_file` logic in the dsmap
A new `reset_state` method is introduced to deal with most of that logic. This
move things one layer lower, but the ultimate goal is to deal with most of this
at the DirstateItem level.
This reveal various imperfection with the data passed to update_file by
`mergestate.recordupdates`, however this is orthogonal to this patch and should
be dealt with at a higher level.
Differential Revision: https://phab.mercurial-scm.org/D11134
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Mon, 19 Jul 2021 07:23:55 +0200 |
parents | 94e38822d395 |
children | f2a9db29cb2d |
rev | line source |
---|---|
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
1 use crate::dirstate::status::IgnoreFnType; |
47347
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
2 use crate::dirstate_tree::dirstate_map::BorrowedPath; |
47333
69530e5d4fe5
dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents:
47331
diff
changeset
|
3 use crate::dirstate_tree::dirstate_map::ChildNodesRef; |
47112
d5956136d19d
dirstate-tree: Give to `status()` mutable access to the `DirstateMap`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
4 use crate::dirstate_tree::dirstate_map::DirstateMap; |
47349
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
5 use crate::dirstate_tree::dirstate_map::NodeData; |
47333
69530e5d4fe5
dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents:
47331
diff
changeset
|
6 use crate::dirstate_tree::dirstate_map::NodeRef; |
47335
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
7 use crate::dirstate_tree::on_disk::DirstateV2ParseError; |
47349
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
8 use crate::dirstate_tree::on_disk::Timestamp; |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
9 use crate::matchers::get_ignore_function; |
47112
d5956136d19d
dirstate-tree: Give to `status()` mutable access to the `DirstateMap`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
10 use crate::matchers::Matcher; |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
11 use crate::utils::files::get_bytes_from_os_string; |
47338
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
12 use crate::utils::files::get_path_from_bytes; |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
13 use crate::utils::hg_path::HgPath; |
47115
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47114
diff
changeset
|
14 use crate::BadMatch; |
47112
d5956136d19d
dirstate-tree: Give to `status()` mutable access to the `DirstateMap`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
15 use crate::DirstateStatus; |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
16 use crate::EntryState; |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
17 use crate::HgPathBuf; |
47112
d5956136d19d
dirstate-tree: Give to `status()` mutable access to the `DirstateMap`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
18 use crate::PatternFileWarning; |
d5956136d19d
dirstate-tree: Give to `status()` mutable access to the `DirstateMap`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
19 use crate::StatusError; |
d5956136d19d
dirstate-tree: Give to `status()` mutable access to the `DirstateMap`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
20 use crate::StatusOptions; |
47118
c92e63762573
dirstate-tree: Add #[timed] attribute to `status` and `DirstateMap::read`
Simon Sapin <simon.sapin@octobus.net>
parents:
47117
diff
changeset
|
21 use micro_timer::timed; |
47117
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47115
diff
changeset
|
22 use rayon::prelude::*; |
47409
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47350
diff
changeset
|
23 use sha1::{Digest, Sha1}; |
47349
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
24 use std::borrow::Cow; |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
25 use std::io; |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
26 use std::path::Path; |
47112
d5956136d19d
dirstate-tree: Give to `status()` mutable access to the `DirstateMap`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
27 use std::path::PathBuf; |
47117
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47115
diff
changeset
|
28 use std::sync::Mutex; |
47349
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
29 use std::time::SystemTime; |
47112
d5956136d19d
dirstate-tree: Give to `status()` mutable access to the `DirstateMap`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
30 |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
31 /// 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:
47112
diff
changeset
|
32 /// changeset. |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
33 /// |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
34 /// 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:
47112
diff
changeset
|
35 /// 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:
47112
diff
changeset
|
36 /// 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:
47112
diff
changeset
|
37 /// 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:
47112
diff
changeset
|
38 /// 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:
47112
diff
changeset
|
39 /// `options` we may need to traverse the remaining subtree. |
47118
c92e63762573
dirstate-tree: Add #[timed] attribute to `status` and `DirstateMap::read`
Simon Sapin <simon.sapin@octobus.net>
parents:
47117
diff
changeset
|
40 #[timed] |
47336
8d0260d0dbc9
dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents:
47335
diff
changeset
|
41 pub fn status<'tree, 'on_disk: 'tree>( |
8d0260d0dbc9
dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents:
47335
diff
changeset
|
42 dmap: &'tree mut DirstateMap<'on_disk>, |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
43 matcher: &(dyn Matcher + Sync), |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
44 root_dir: PathBuf, |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
45 ignore_files: Vec<PathBuf>, |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
46 options: StatusOptions, |
47347
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
47 ) -> Result<(DirstateStatus<'on_disk>, Vec<PatternFileWarning>), StatusError> { |
47409
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47350
diff
changeset
|
48 let (ignore_fn, warnings, patterns_changed): (IgnoreFnType, _, _) = |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
49 if options.list_ignored || options.list_unknown { |
47409
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47350
diff
changeset
|
50 let mut hasher = Sha1::new(); |
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47350
diff
changeset
|
51 let (ignore_fn, warnings) = get_ignore_function( |
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47350
diff
changeset
|
52 ignore_files, |
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47350
diff
changeset
|
53 &root_dir, |
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47350
diff
changeset
|
54 &mut |pattern_bytes| hasher.update(pattern_bytes), |
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47350
diff
changeset
|
55 )?; |
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47350
diff
changeset
|
56 let new_hash = *hasher.finalize().as_ref(); |
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47350
diff
changeset
|
57 let changed = new_hash != dmap.ignore_patterns_hash; |
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47350
diff
changeset
|
58 dmap.ignore_patterns_hash = new_hash; |
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47350
diff
changeset
|
59 (ignore_fn, warnings, Some(changed)) |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
60 } else { |
47409
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47350
diff
changeset
|
61 (Box::new(|&_| true), vec![], None) |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
62 }; |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
63 |
47117
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47115
diff
changeset
|
64 let common = StatusCommon { |
47336
8d0260d0dbc9
dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents:
47335
diff
changeset
|
65 dmap, |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
66 options, |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
67 matcher, |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
68 ignore_fn, |
47349
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
69 outcome: Default::default(), |
47409
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47350
diff
changeset
|
70 ignore_patterns_have_changed: patterns_changed, |
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47350
diff
changeset
|
71 new_cachable_directories: Default::default(), |
47474
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47409
diff
changeset
|
72 outated_cached_directories: Default::default(), |
47349
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
73 filesystem_time_at_status_start: filesystem_now(&root_dir).ok(), |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
74 }; |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
75 let is_at_repo_root = true; |
47347
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
76 let hg_path = &BorrowedPath::OnDisk(HgPath::new("")); |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
77 let has_ignored_ancestor = false; |
47349
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
78 let root_cached_mtime = None; |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
79 let root_dir_metadata = None; |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
80 // 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:
47347
diff
changeset
|
81 // (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:
47347
diff
changeset
|
82 // followed, using `std::fs::symlink_metadata`.) |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
83 common.traverse_fs_directory_and_dirstate( |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
84 has_ignored_ancestor, |
47333
69530e5d4fe5
dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents:
47331
diff
changeset
|
85 dmap.root.as_ref(), |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
86 hg_path, |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
87 &root_dir, |
47349
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
88 root_dir_metadata, |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
89 root_cached_mtime, |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
90 is_at_repo_root, |
47335
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
91 )?; |
47350
04d1f17f49e7
dirstate-v2: Write .hg/dirstate back to disk on directory cache changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47349
diff
changeset
|
92 let mut outcome = common.outcome.into_inner().unwrap(); |
47409
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47350
diff
changeset
|
93 let new_cachable = common.new_cachable_directories.into_inner().unwrap(); |
47474
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47409
diff
changeset
|
94 let outdated = common.outated_cached_directories.into_inner().unwrap(); |
47409
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47350
diff
changeset
|
95 |
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47350
diff
changeset
|
96 outcome.dirty = common.ignore_patterns_have_changed == Some(true) |
47474
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47409
diff
changeset
|
97 || !outdated.is_empty() |
47409
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47350
diff
changeset
|
98 || !new_cachable.is_empty(); |
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47350
diff
changeset
|
99 |
47474
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47409
diff
changeset
|
100 // 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:
47409
diff
changeset
|
101 // directory is both |
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47409
diff
changeset
|
102 for path in &outdated { |
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47409
diff
changeset
|
103 let node = dmap.get_or_insert(path)?; |
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47409
diff
changeset
|
104 if let NodeData::CachedDirectory { .. } = &node.data { |
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47409
diff
changeset
|
105 node.data = NodeData::None |
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47409
diff
changeset
|
106 } |
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47409
diff
changeset
|
107 } |
47409
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47350
diff
changeset
|
108 for (path, mtime) in &new_cachable { |
47474
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47409
diff
changeset
|
109 let node = dmap.get_or_insert(path)?; |
47349
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
110 match &node.data { |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
111 NodeData::Entry(_) => {} // Don’t overwrite an entry |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
112 NodeData::CachedDirectory { .. } | NodeData::None => { |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
113 node.data = NodeData::CachedDirectory { mtime: *mtime } |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
114 } |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
115 } |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
116 } |
47409
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47350
diff
changeset
|
117 |
47349
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
118 Ok((outcome, warnings)) |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
119 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
120 |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
121 /// 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:
47112
diff
changeset
|
122 /// number of parameters passed to functions. |
47347
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
123 struct StatusCommon<'a, 'tree, 'on_disk: 'tree> { |
47336
8d0260d0dbc9
dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents:
47335
diff
changeset
|
124 dmap: &'tree DirstateMap<'on_disk>, |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
125 options: StatusOptions, |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
126 matcher: &'a (dyn Matcher + Sync), |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
127 ignore_fn: IgnoreFnType<'a>, |
47347
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
128 outcome: Mutex<DirstateStatus<'on_disk>>, |
47409
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47350
diff
changeset
|
129 new_cachable_directories: Mutex<Vec<(Cow<'on_disk, HgPath>, Timestamp)>>, |
47474
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47409
diff
changeset
|
130 outated_cached_directories: Mutex<Vec<Cow<'on_disk, HgPath>>>, |
47409
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47350
diff
changeset
|
131 |
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47350
diff
changeset
|
132 /// 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:
47350
diff
changeset
|
133 /// 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:
47350
diff
changeset
|
134 /// 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:
47350
diff
changeset
|
135 /// and therefore isn’t reading `.hgignore`. |
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47350
diff
changeset
|
136 ignore_patterns_have_changed: Option<bool>, |
47349
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
137 |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
138 /// 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:
47347
diff
changeset
|
139 /// and possibly truncated by the filesystem. |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
140 filesystem_time_at_status_start: Option<SystemTime>, |
47112
d5956136d19d
dirstate-tree: Give to `status()` mutable access to the `DirstateMap`
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
141 } |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
142 |
47347
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
143 impl<'a, 'tree, 'on_disk> StatusCommon<'a, 'tree, 'on_disk> { |
47115
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47114
diff
changeset
|
144 fn read_dir( |
47117
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47115
diff
changeset
|
145 &self, |
47115
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47114
diff
changeset
|
146 hg_path: &HgPath, |
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47114
diff
changeset
|
147 fs_path: &Path, |
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47114
diff
changeset
|
148 is_at_repo_root: bool, |
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47114
diff
changeset
|
149 ) -> Result<Vec<DirEntry>, ()> { |
47338
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
150 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:
47336
diff
changeset
|
151 .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:
47336
diff
changeset
|
152 } |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
153 |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
154 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:
47336
diff
changeset
|
155 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:
47336
diff
changeset
|
156 self.outcome |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
157 .lock() |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
158 .unwrap() |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
159 .bad |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
160 .push((hg_path.to_owned().into(), BadMatch::OsError(errno))) |
47115
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47114
diff
changeset
|
161 } |
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47114
diff
changeset
|
162 |
47474
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47409
diff
changeset
|
163 fn check_for_outdated_directory_cache( |
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47409
diff
changeset
|
164 &self, |
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47409
diff
changeset
|
165 dirstate_node: &NodeRef<'tree, 'on_disk>, |
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47409
diff
changeset
|
166 ) -> Result<(), DirstateV2ParseError> { |
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47409
diff
changeset
|
167 if self.ignore_patterns_have_changed == Some(true) |
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47409
diff
changeset
|
168 && dirstate_node.cached_directory_mtime().is_some() |
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47409
diff
changeset
|
169 { |
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47409
diff
changeset
|
170 self.outated_cached_directories.lock().unwrap().push( |
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47409
diff
changeset
|
171 dirstate_node |
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47409
diff
changeset
|
172 .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:
47409
diff
changeset
|
173 .detach_from_tree(), |
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47409
diff
changeset
|
174 ) |
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47409
diff
changeset
|
175 } |
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47409
diff
changeset
|
176 Ok(()) |
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47409
diff
changeset
|
177 } |
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47409
diff
changeset
|
178 |
47349
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
179 /// 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:
47347
diff
changeset
|
180 /// `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:
47347
diff
changeset
|
181 /// need to call `read_dir`. |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
182 fn can_skip_fs_readdir( |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
183 &self, |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
184 directory_metadata: Option<&std::fs::Metadata>, |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
185 cached_directory_mtime: Option<&Timestamp>, |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
186 ) -> bool { |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
187 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:
47347
diff
changeset
|
188 // 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:
47347
diff
changeset
|
189 // dirstate entries. |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
190 // 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:
47347
diff
changeset
|
191 return true; |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
192 } |
47475
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
193 if !self.options.list_ignored |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
194 && 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:
47474
diff
changeset
|
195 { |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
196 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:
47474
diff
changeset
|
197 // 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:
47474
diff
changeset
|
198 // 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:
47474
diff
changeset
|
199 // directory eligible for `read_dir` caching. |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
200 if let Some(meta) = directory_metadata { |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
201 if let Ok(current_mtime) = meta.modified() { |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
202 if current_mtime == cached_mtime.into() { |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
203 // The mtime of that directory has not changed |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
204 // since then, which means that the results of |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
205 // `read_dir` should also be unchanged. |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
206 return true; |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
207 } |
47349
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
208 } |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
209 } |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
210 } |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
211 } |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
212 false |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
213 } |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
214 |
47475
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
215 /// 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:
47474
diff
changeset
|
216 /// corresponding dirstate node or are ignored. |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
217 fn traverse_fs_directory_and_dirstate( |
47117
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47115
diff
changeset
|
218 &self, |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
219 has_ignored_ancestor: bool, |
47347
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
220 dirstate_nodes: ChildNodesRef<'tree, 'on_disk>, |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
221 directory_hg_path: &BorrowedPath<'tree, 'on_disk>, |
47115
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47114
diff
changeset
|
222 directory_fs_path: &Path, |
47349
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
223 directory_metadata: Option<&std::fs::Metadata>, |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
224 cached_directory_mtime: Option<&Timestamp>, |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
225 is_at_repo_root: bool, |
47349
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
226 ) -> Result<bool, DirstateV2ParseError> { |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
227 if self.can_skip_fs_readdir(directory_metadata, cached_directory_mtime) |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
228 { |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
229 dirstate_nodes |
47338
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
230 .par_iter() |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
231 .map(|dirstate_node| { |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
232 let fs_path = directory_fs_path.join(get_path_from_bytes( |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
233 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:
47336
diff
changeset
|
234 )); |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
235 match std::fs::symlink_metadata(&fs_path) { |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
236 Ok(fs_metadata) => self.traverse_fs_and_dirstate( |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
237 &fs_path, |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
238 &fs_metadata, |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
239 dirstate_node, |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
240 has_ignored_ancestor, |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
241 ), |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
242 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:
47336
diff
changeset
|
243 self.traverse_dirstate_only(dirstate_node) |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
244 } |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
245 Err(error) => { |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
246 let hg_path = |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
247 dirstate_node.full_path(self.dmap.on_disk)?; |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
248 Ok(self.io_error(error, hg_path)) |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
249 } |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
250 } |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
251 }) |
47349
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
252 .collect::<Result<_, _>>()?; |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
253 |
47475
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
254 // 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:
47474
diff
changeset
|
255 let children_all_have_dirstate_node_or_are_ignored = false; |
47349
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
256 |
47475
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
257 return Ok(children_all_have_dirstate_node_or_are_ignored); |
47338
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
258 } |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
259 |
47115
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47114
diff
changeset
|
260 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:
47114
diff
changeset
|
261 directory_hg_path, |
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47114
diff
changeset
|
262 directory_fs_path, |
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47114
diff
changeset
|
263 is_at_repo_root, |
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47114
diff
changeset
|
264 ) { |
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47114
diff
changeset
|
265 entries |
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47114
diff
changeset
|
266 } else { |
47346
5e12b6bfdd3e
dirstate-tree: Fix status algorithm with unreadable directory
Simon Sapin <simon.sapin@octobus.net>
parents:
47338
diff
changeset
|
267 // Treat an unreadable directory (typically because of insufficient |
5e12b6bfdd3e
dirstate-tree: Fix status algorithm with unreadable directory
Simon Sapin <simon.sapin@octobus.net>
parents:
47338
diff
changeset
|
268 // 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:
47338
diff
changeset
|
269 // 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:
47338
diff
changeset
|
270 Vec::new() |
47115
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47114
diff
changeset
|
271 }; |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
272 |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
273 // `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:
47112
diff
changeset
|
274 |
47333
69530e5d4fe5
dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents:
47331
diff
changeset
|
275 let dirstate_nodes = dirstate_nodes.sorted(); |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
276 // `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:
47112
diff
changeset
|
277 // https://github.com/rust-lang/rust/issues/34162 |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
278 fs_entries.sort_unstable_by(|e1, e2| e1.base_name.cmp(&e2.base_name)); |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
279 |
47335
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
280 // 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:
47333
diff
changeset
|
281 // callback below |
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
282 for dirstate_node in &dirstate_nodes { |
47336
8d0260d0dbc9
dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents:
47335
diff
changeset
|
283 dirstate_node.base_name(self.dmap.on_disk)?; |
47335
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
284 } |
47117
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47115
diff
changeset
|
285 itertools::merge_join_by( |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
286 dirstate_nodes, |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
287 &fs_entries, |
47333
69530e5d4fe5
dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents:
47331
diff
changeset
|
288 |dirstate_node, fs_entry| { |
47335
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
289 // This `unwrap` never panics because we already propagated |
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
290 // those errors above |
47336
8d0260d0dbc9
dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents:
47335
diff
changeset
|
291 dirstate_node |
8d0260d0dbc9
dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents:
47335
diff
changeset
|
292 .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:
47335
diff
changeset
|
293 .unwrap() |
8d0260d0dbc9
dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents:
47335
diff
changeset
|
294 .cmp(&fs_entry.base_name) |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
295 }, |
47117
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47115
diff
changeset
|
296 ) |
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47115
diff
changeset
|
297 .par_bridge() |
47335
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
298 .map(|pair| { |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
299 use itertools::EitherOrBoth::*; |
47475
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
300 let has_dirstate_node_or_is_ignored; |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
301 match pair { |
47475
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
302 Both(dirstate_node, fs_entry) => { |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
303 self.traverse_fs_and_dirstate( |
47338
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
304 &fs_entry.full_path, |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
305 &fs_entry.metadata, |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
306 dirstate_node, |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
307 has_ignored_ancestor, |
47475
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
308 )?; |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
309 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:
47474
diff
changeset
|
310 } |
47333
69530e5d4fe5
dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents:
47331
diff
changeset
|
311 Left(dirstate_node) => { |
47475
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
312 self.traverse_dirstate_only(dirstate_node)?; |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
313 has_dirstate_node_or_is_ignored = true; |
47333
69530e5d4fe5
dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents:
47331
diff
changeset
|
314 } |
47475
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
315 Right(fs_entry) => { |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
316 has_dirstate_node_or_is_ignored = self.traverse_fs_only( |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
317 has_ignored_ancestor, |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
318 directory_hg_path, |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
319 fs_entry, |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
320 ) |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
321 } |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
322 } |
47475
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
323 Ok(has_dirstate_node_or_is_ignored) |
47117
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47115
diff
changeset
|
324 }) |
47475
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
325 .try_reduce(|| true, |a, b| Ok(a && b)) |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
326 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
327 |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
328 fn traverse_fs_and_dirstate( |
47117
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47115
diff
changeset
|
329 &self, |
47338
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
330 fs_path: &Path, |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
331 fs_metadata: &std::fs::Metadata, |
47347
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
332 dirstate_node: NodeRef<'tree, 'on_disk>, |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
333 has_ignored_ancestor: bool, |
47335
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
334 ) -> Result<(), DirstateV2ParseError> { |
47474
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47409
diff
changeset
|
335 self.check_for_outdated_directory_cache(&dirstate_node)?; |
47347
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
336 let hg_path = &dirstate_node.full_path_borrowed(self.dmap.on_disk)?; |
47338
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
337 let file_type = fs_metadata.file_type(); |
47114
aeb03758f37a
dirstate-tree: Ignore FIFOs etc. in the status algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47113
diff
changeset
|
338 let file_or_symlink = file_type.is_file() || file_type.is_symlink(); |
aeb03758f37a
dirstate-tree: Ignore FIFOs etc. in the status algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47113
diff
changeset
|
339 if !file_or_symlink { |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
340 // 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:
47112
diff
changeset
|
341 // `hg rm` or similar) or deleted before it could be |
47114
aeb03758f37a
dirstate-tree: Ignore FIFOs etc. in the status algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47113
diff
changeset
|
342 // replaced by a directory or something else. |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
343 self.mark_removed_or_deleted_if_file( |
47347
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
344 &hg_path, |
47335
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
345 dirstate_node.state()?, |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
346 ); |
47114
aeb03758f37a
dirstate-tree: Ignore FIFOs etc. in the status algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47113
diff
changeset
|
347 } |
aeb03758f37a
dirstate-tree: Ignore FIFOs etc. in the status algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47113
diff
changeset
|
348 if file_type.is_dir() { |
aeb03758f37a
dirstate-tree: Ignore FIFOs etc. in the status algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47113
diff
changeset
|
349 if self.options.collect_traversed_dirs { |
47347
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
350 self.outcome |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
351 .lock() |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
352 .unwrap() |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
353 .traversed |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
354 .push(hg_path.detach_from_tree()) |
47114
aeb03758f37a
dirstate-tree: Ignore FIFOs etc. in the status algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47113
diff
changeset
|
355 } |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
356 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:
47112
diff
changeset
|
357 let is_at_repo_root = false; |
47475
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
358 let children_all_have_dirstate_node_or_are_ignored = self |
47349
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
359 .traverse_fs_directory_and_dirstate( |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
360 is_ignored, |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
361 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:
47347
diff
changeset
|
362 hg_path, |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
363 fs_path, |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
364 Some(fs_metadata), |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
365 dirstate_node.cached_directory_mtime(), |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
366 is_at_repo_root, |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
367 )?; |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
368 self.maybe_save_directory_mtime( |
47475
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
369 children_all_have_dirstate_node_or_are_ignored, |
47349
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
370 fs_metadata, |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
371 dirstate_node, |
47335
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
372 )? |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
373 } else { |
47114
aeb03758f37a
dirstate-tree: Ignore FIFOs etc. in the status algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47113
diff
changeset
|
374 if file_or_symlink && self.matcher.matches(hg_path) { |
47335
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
375 if let Some(state) = dirstate_node.state()? { |
47333
69530e5d4fe5
dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents:
47331
diff
changeset
|
376 match state { |
47347
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
377 EntryState::Added => self |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
378 .outcome |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
379 .lock() |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
380 .unwrap() |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
381 .added |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
382 .push(hg_path.detach_from_tree()), |
47117
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47115
diff
changeset
|
383 EntryState::Removed => self |
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47115
diff
changeset
|
384 .outcome |
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47115
diff
changeset
|
385 .lock() |
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47115
diff
changeset
|
386 .unwrap() |
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47115
diff
changeset
|
387 .removed |
47347
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
388 .push(hg_path.detach_from_tree()), |
47117
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47115
diff
changeset
|
389 EntryState::Merged => self |
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47115
diff
changeset
|
390 .outcome |
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47115
diff
changeset
|
391 .lock() |
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47115
diff
changeset
|
392 .unwrap() |
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47115
diff
changeset
|
393 .modified |
47347
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
394 .push(hg_path.detach_from_tree()), |
47338
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
395 EntryState::Normal => self |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
396 .handle_normal_file(&dirstate_node, fs_metadata)?, |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
397 // This variant is not used in DirstateMap |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
398 // nodes |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
399 EntryState::Unknown => unreachable!(), |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
400 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
401 } else { |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
402 // `node.entry.is_none()` indicates a "directory" |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
403 // node, but the filesystem has a file |
47475
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
404 self.mark_unknown_or_ignored( |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
405 has_ignored_ancestor, |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
406 hg_path, |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
407 ); |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
408 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
409 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
410 |
47336
8d0260d0dbc9
dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents:
47335
diff
changeset
|
411 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:
47335
diff
changeset
|
412 { |
47335
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
413 self.traverse_dirstate_only(child_node)? |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
414 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
415 } |
47335
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
416 Ok(()) |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
417 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
418 |
47349
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
419 fn maybe_save_directory_mtime( |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
420 &self, |
47475
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
421 children_all_have_dirstate_node_or_are_ignored: bool, |
47349
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
422 directory_metadata: &std::fs::Metadata, |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
423 dirstate_node: NodeRef<'tree, 'on_disk>, |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
424 ) -> Result<(), DirstateV2ParseError> { |
47475
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
425 if children_all_have_dirstate_node_or_are_ignored { |
47349
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
426 // All filesystem directory entries from `read_dir` have a |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
427 // corresponding node in the dirstate, so we can reconstitute the |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
428 // names of those entries without calling `read_dir` again. |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
429 if let (Some(status_start), Ok(directory_mtime)) = ( |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
430 &self.filesystem_time_at_status_start, |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
431 directory_metadata.modified(), |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
432 ) { |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
433 // Although the Rust standard library’s `SystemTime` type |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
434 // has nanosecond precision, the times reported for a |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
435 // directory’s (or file’s) modified time may have lower |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
436 // resolution based on the filesystem (for example ext3 |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
437 // only stores integer seconds), kernel (see |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
438 // https://stackoverflow.com/a/14393315/1162888), etc. |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
439 if &directory_mtime >= status_start { |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
440 // The directory was modified too recently, don’t cache its |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
441 // `read_dir` results. |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
442 // |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
443 // A timeline like this is possible: |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
444 // |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
445 // 1. A change to this directory (direct child was |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
446 // added or removed) cause its mtime to be set |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
447 // (possibly truncated) to `directory_mtime` |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
448 // 2. This `status` algorithm calls `read_dir` |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
449 // 3. An other change is made to the same directory is |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
450 // made so that calling `read_dir` agin would give |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
451 // different results, but soon enough after 1. that |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
452 // the mtime stays the same |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
453 // |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
454 // On a system where the time resolution poor, this |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
455 // scenario is not unlikely if all three steps are caused |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
456 // by the same script. |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
457 } else { |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
458 // We’ve observed (through `status_start`) that time has |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
459 // “progressed” since `directory_mtime`, so any further |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
460 // change to this directory is extremely likely to cause a |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
461 // different mtime. |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
462 // |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
463 // Having the same mtime again is not entirely impossible |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
464 // since the system clock is not monotonous. It could jump |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
465 // backward to some point before `directory_mtime`, then a |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
466 // directory change could potentially happen during exactly |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
467 // the wrong tick. |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
468 // |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
469 // We deem this scenario (unlike the previous one) to be |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
470 // unlikely enough in practice. |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
471 let timestamp = directory_mtime.into(); |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
472 let cached = dirstate_node.cached_directory_mtime(); |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
473 if cached != Some(×tamp) { |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
474 let hg_path = dirstate_node |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
475 .full_path_borrowed(self.dmap.on_disk)? |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
476 .detach_from_tree(); |
47409
0ef8231e413f
dirstate-v2: Store a hash of ignore patterns (.hgignore)
Simon Sapin <simon.sapin@octobus.net>
parents:
47350
diff
changeset
|
477 self.new_cachable_directories |
47349
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
478 .lock() |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
479 .unwrap() |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
480 .push((hg_path, timestamp)) |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
481 } |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
482 } |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
483 } |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
484 } |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
485 Ok(()) |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
486 } |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
487 |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
488 /// A file with `EntryState::Normal` in the dirstate was found in the |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
489 /// filesystem |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
490 fn handle_normal_file( |
47117
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47115
diff
changeset
|
491 &self, |
47347
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
492 dirstate_node: &NodeRef<'tree, 'on_disk>, |
47338
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
493 fs_metadata: &std::fs::Metadata, |
47335
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
494 ) -> Result<(), DirstateV2ParseError> { |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
495 // Keep the low 31 bits |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
496 fn truncate_u64(value: u64) -> i32 { |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
497 (value & 0x7FFF_FFFF) as i32 |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
498 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
499 fn truncate_i64(value: i64) -> i32 { |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
500 (value & 0x7FFF_FFFF) as i32 |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
501 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
502 |
47333
69530e5d4fe5
dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents:
47331
diff
changeset
|
503 let entry = dirstate_node |
47335
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
504 .entry()? |
47333
69530e5d4fe5
dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents:
47331
diff
changeset
|
505 .expect("handle_normal_file called with entry-less node"); |
47347
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
506 let hg_path = &dirstate_node.full_path_borrowed(self.dmap.on_disk)?; |
47338
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
507 let mode_changed = |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
508 || self.options.check_exec && entry.mode_changed(fs_metadata); |
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
509 let size_changed = entry.size != truncate_u64(fs_metadata.len()); |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
510 if entry.size >= 0 |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
511 && size_changed |
47338
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
512 && fs_metadata.file_type().is_symlink() |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
513 { |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
514 // issue6456: Size returned may be longer due to encryption |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
515 // on EXT-4 fscrypt. TODO maybe only do it on EXT4? |
47347
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
516 self.outcome |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
517 .lock() |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
518 .unwrap() |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
519 .unsure |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
520 .push(hg_path.detach_from_tree()) |
47335
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
521 } else if dirstate_node.has_copy_source() |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
522 || entry.is_from_other_parent() |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
523 || (entry.size >= 0 && (size_changed || mode_changed())) |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
524 { |
47347
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
525 self.outcome |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
526 .lock() |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
527 .unwrap() |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
528 .modified |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
529 .push(hg_path.detach_from_tree()) |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
530 } else { |
47338
f27f2afb15da
dirstate-tree: Skip readdir() in `hg status -mard`
Simon Sapin <simon.sapin@octobus.net>
parents:
47336
diff
changeset
|
531 let mtime = mtime_seconds(fs_metadata); |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
532 if truncate_i64(mtime) != entry.mtime |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
533 || mtime == self.options.last_normal_time |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
534 { |
47347
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
535 self.outcome |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
536 .lock() |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
537 .unwrap() |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
538 .unsure |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
539 .push(hg_path.detach_from_tree()) |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
540 } else if self.options.list_clean { |
47347
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
541 self.outcome |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
542 .lock() |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
543 .unwrap() |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
544 .clean |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
545 .push(hg_path.detach_from_tree()) |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
546 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
547 } |
47335
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
548 Ok(()) |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
549 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
550 |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
551 /// A node in the dirstate tree has no corresponding filesystem entry |
47335
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
552 fn traverse_dirstate_only( |
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
553 &self, |
47347
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
554 dirstate_node: NodeRef<'tree, 'on_disk>, |
47335
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
555 ) -> Result<(), DirstateV2ParseError> { |
47474
c657beacdf2e
dirstate-v2: Drop cached read_dir results after .hgignore changes
Simon Sapin <simon.sapin@octobus.net>
parents:
47409
diff
changeset
|
556 self.check_for_outdated_directory_cache(&dirstate_node)?; |
47333
69530e5d4fe5
dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents:
47331
diff
changeset
|
557 self.mark_removed_or_deleted_if_file( |
47347
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
558 &dirstate_node.full_path_borrowed(self.dmap.on_disk)?, |
47335
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
559 dirstate_node.state()?, |
47333
69530e5d4fe5
dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents:
47331
diff
changeset
|
560 ); |
69530e5d4fe5
dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents:
47331
diff
changeset
|
561 dirstate_node |
47336
8d0260d0dbc9
dirstate-v2: Make the dirstate bytes buffer available in more places
Simon Sapin <simon.sapin@octobus.net>
parents:
47335
diff
changeset
|
562 .children(self.dmap.on_disk)? |
47333
69530e5d4fe5
dirstate-tree: Add `NodeRef` and `ChildNodesRef` enums
Simon Sapin <simon.sapin@octobus.net>
parents:
47331
diff
changeset
|
563 .par_iter() |
47335
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47333
diff
changeset
|
564 .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:
47333
diff
changeset
|
565 .collect() |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
566 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
567 |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
568 /// 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:
47112
diff
changeset
|
569 /// filesystem |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
570 /// |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
571 /// Does nothing on a "directory" node |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
572 fn mark_removed_or_deleted_if_file( |
47117
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47115
diff
changeset
|
573 &self, |
47347
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
574 hg_path: &BorrowedPath<'tree, 'on_disk>, |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
575 dirstate_node_state: Option<EntryState>, |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
576 ) { |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
577 if let Some(state) = dirstate_node_state { |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
578 if self.matcher.matches(hg_path) { |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
579 if let EntryState::Removed = state { |
47347
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
580 self.outcome |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
581 .lock() |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
582 .unwrap() |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
583 .removed |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
584 .push(hg_path.detach_from_tree()) |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
585 } else { |
47347
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
586 self.outcome |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
587 .lock() |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
588 .unwrap() |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
589 .deleted |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
590 .push(hg_path.detach_from_tree()) |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
591 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
592 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
593 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
594 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
595 |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
596 /// Something in the filesystem has no corresponding dirstate node |
47475
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
597 /// |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
598 /// Returns whether that path is ignored |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
599 fn traverse_fs_only( |
47117
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47115
diff
changeset
|
600 &self, |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
601 has_ignored_ancestor: bool, |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
602 directory_hg_path: &HgPath, |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
603 fs_entry: &DirEntry, |
47475
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
604 ) -> bool { |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
605 let hg_path = directory_hg_path.join(&fs_entry.base_name); |
47114
aeb03758f37a
dirstate-tree: Ignore FIFOs etc. in the status algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47113
diff
changeset
|
606 let file_type = fs_entry.metadata.file_type(); |
aeb03758f37a
dirstate-tree: Ignore FIFOs etc. in the status algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47113
diff
changeset
|
607 let file_or_symlink = file_type.is_file() || file_type.is_symlink(); |
aeb03758f37a
dirstate-tree: Ignore FIFOs etc. in the status algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47113
diff
changeset
|
608 if file_type.is_dir() { |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
609 let is_ignored = |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
610 has_ignored_ancestor || (self.ignore_fn)(&hg_path); |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
611 let traverse_children = if is_ignored { |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
612 // Descendants of an ignored directory are all ignored |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
613 self.options.list_ignored |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
614 } else { |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
615 // 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:
47112
diff
changeset
|
616 // ignored |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
617 self.options.list_unknown || self.options.list_ignored |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
618 }; |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
619 if traverse_children { |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
620 let is_at_repo_root = false; |
47115
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47114
diff
changeset
|
621 if let Ok(children_fs_entries) = self.read_dir( |
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47114
diff
changeset
|
622 &hg_path, |
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47114
diff
changeset
|
623 &fs_entry.full_path, |
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47114
diff
changeset
|
624 is_at_repo_root, |
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47114
diff
changeset
|
625 ) { |
47117
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47115
diff
changeset
|
626 children_fs_entries.par_iter().for_each(|child_fs_entry| { |
47115
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47114
diff
changeset
|
627 self.traverse_fs_only( |
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47114
diff
changeset
|
628 is_ignored, |
1b4f0f819f92
dirstate-tree: Handle I/O errors in status
Simon Sapin <simon.sapin@octobus.net>
parents:
47114
diff
changeset
|
629 &hg_path, |
47117
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47115
diff
changeset
|
630 child_fs_entry, |
47475
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
631 ); |
47117
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47115
diff
changeset
|
632 }) |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
633 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
634 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
635 if self.options.collect_traversed_dirs { |
47117
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47115
diff
changeset
|
636 self.outcome.lock().unwrap().traversed.push(hg_path.into()) |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
637 } |
47475
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
638 is_ignored |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
639 } else { |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
640 if file_or_symlink { |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
641 if self.matcher.matches(&hg_path) { |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
642 self.mark_unknown_or_ignored( |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
643 has_ignored_ancestor, |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
644 &BorrowedPath::InMemory(&hg_path), |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
645 ) |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
646 } else { |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
647 // 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:
47474
diff
changeset
|
648 // 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:
47474
diff
changeset
|
649 // 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:
47474
diff
changeset
|
650 // 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:
47474
diff
changeset
|
651 // directory. |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
652 false |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
653 } |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
654 } else { |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
655 // 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:
47474
diff
changeset
|
656 // Treat it like an ignored file. |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
657 true |
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
658 } |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
659 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
660 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
661 |
47475
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
662 /// Returns whether that path is ignored |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
663 fn mark_unknown_or_ignored( |
47117
60d852ae7e7b
dirstate-tree: Paralellize the status algorithm with Rayon
Simon Sapin <simon.sapin@octobus.net>
parents:
47115
diff
changeset
|
664 &self, |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
665 has_ignored_ancestor: bool, |
47347
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
666 hg_path: &BorrowedPath<'_, 'on_disk>, |
47475
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
667 ) -> bool { |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
668 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:
47112
diff
changeset
|
669 if is_ignored { |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
670 if self.options.list_ignored { |
47347
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
671 self.outcome |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
672 .lock() |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
673 .unwrap() |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
674 .ignored |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
675 .push(hg_path.detach_from_tree()) |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
676 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
677 } else { |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
678 if self.options.list_unknown { |
47347
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
679 self.outcome |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
680 .lock() |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
681 .unwrap() |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
682 .unknown |
73ddcedeaadf
dirstate-tree: Change status() results to not borrow DirstateMap
Simon Sapin <simon.sapin@octobus.net>
parents:
47346
diff
changeset
|
683 .push(hg_path.detach_from_tree()) |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
684 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
685 } |
47475
94e38822d395
status: Extend read_dir caching to directories with ignored files
Simon Sapin <simon.sapin@octobus.net>
parents:
47474
diff
changeset
|
686 is_ignored |
47113
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
687 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
688 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
689 |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
690 #[cfg(unix)] // TODO |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
691 fn mtime_seconds(metadata: &std::fs::Metadata) -> i64 { |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
692 // Going through `Metadata::modified()` would be portable, but would take |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
693 // care to construct a `SystemTime` value with sub-second precision just |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
694 // for us to throw that away here. |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
695 use std::os::unix::fs::MetadataExt; |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
696 metadata.mtime() |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
697 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
698 |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
699 struct DirEntry { |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
700 base_name: HgPathBuf, |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
701 full_path: PathBuf, |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
702 metadata: std::fs::Metadata, |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
703 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
704 |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
705 impl DirEntry { |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
706 /// Returns **unsorted** entries in the given directory, with name and |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
707 /// metadata. |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
708 /// |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
709 /// If a `.hg` sub-directory is encountered: |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
710 /// |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
711 /// * At the repository root, ignore that sub-directory |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
712 /// * 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:
47112
diff
changeset
|
713 /// list instead. |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
714 fn read_dir(path: &Path, is_at_repo_root: bool) -> io::Result<Vec<Self>> { |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
715 let mut results = Vec::new(); |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
716 for entry in path.read_dir()? { |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
717 let entry = entry?; |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
718 let metadata = entry.metadata()?; |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
719 let name = get_bytes_from_os_string(entry.file_name()); |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
720 // FIXME don't do this when cached |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
721 if name == b".hg" { |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
722 if is_at_repo_root { |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
723 // 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:
47112
diff
changeset
|
724 continue; |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
725 } else if metadata.is_dir() { |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
726 // 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:
47112
diff
changeset
|
727 // skip it entirely. |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
728 return Ok(Vec::new()); |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
729 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
730 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
731 results.push(DirEntry { |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
732 base_name: name.into(), |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
733 full_path: entry.path(), |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
734 metadata, |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
735 }) |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
736 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
737 Ok(results) |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
738 } |
be579775c2d9
dirstate-tree: Add the new `status()` algorithm
Simon Sapin <simon.sapin@octobus.net>
parents:
47112
diff
changeset
|
739 } |
47349
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
740 |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
741 /// 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:
47347
diff
changeset
|
742 /// of the give repository. |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
743 /// |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
744 /// 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:
47347
diff
changeset
|
745 /// 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:
47347
diff
changeset
|
746 /// 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:
47347
diff
changeset
|
747 /// 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:
47347
diff
changeset
|
748 /// 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:
47347
diff
changeset
|
749 /// store timestamps with different resolutions. |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
750 /// |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
751 /// 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:
47347
diff
changeset
|
752 /// 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:
47347
diff
changeset
|
753 /// date/time to be unknown. |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
754 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:
47347
diff
changeset
|
755 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:
47347
diff
changeset
|
756 .metadata()? |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
757 .modified() |
7138c863d0a1
dirstate-v2: Skip readdir in status based on directory mtime
Simon Sapin <simon.sapin@octobus.net>
parents:
47347
diff
changeset
|
758 } |