annotate rust/hg-core/src/update.rs @ 52156:e6a44bc91bc2 stable

rust-update: make `update_from_null` respect `worker.numcpu` config option This was overlooked in the original series. This is important for tests (because we run many at once), and for the occasional end user that wants to keep their CPU usage in check. A future series should clean up this `worker` parameter tunelling business by rewriting the config in Rust, but doing so on stable would be a very bad idea.
author Rapha?l Gom?s <rgomes@octobus.net>
date Tue, 05 Nov 2024 15:21:09 +0100
parents 8b7123c8947b
children 96b113d22b34
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
52084
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
1 //! Tools for moving the repository to a given revision
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
2
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
3 use std::{
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
4 fs::Permissions,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
5 io::Write,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
6 os::unix::fs::{MetadataExt, PermissionsExt},
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
7 path::Path,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
8 time::Duration,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
9 };
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
10
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
11 use crate::{
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
12 dirstate::{ParentFileData, TruncatedTimestamp},
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
13 dirstate_tree::{
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
14 dirstate_map::DirstateEntryReset, on_disk::write_tracked_key,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
15 },
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
16 errors::{HgError, IoResultExt},
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
17 exit_codes,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
18 filelog::Filelog,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
19 narrow,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
20 node::NULL_NODE,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
21 operations::{list_rev_tracked_files, ExpandedManifestEntry},
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
22 progress::Progress,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
23 repo::Repo,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
24 sparse,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
25 utils::{
52156
e6a44bc91bc2 rust-update: make `update_from_null` respect `worker.numcpu` config option
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52084
diff changeset
26 cap_default_rayon_threads,
52084
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
27 files::{filesystem_now, get_path_from_bytes},
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
28 hg_path::{hg_path_to_path_buf, HgPath, HgPathError},
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
29 path_auditor::PathAuditor,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
30 },
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
31 vfs::{is_on_nfs_mount, VfsImpl},
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
32 DirstateParents, RevlogError, RevlogOpenOptions, UncheckedRevision,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
33 };
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
34 use crossbeam_channel::{Receiver, Sender};
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
35 use rayon::prelude::*;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
36
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
37 fn write_dirstate(repo: &Repo) -> Result<(), HgError> {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
38 repo.write_dirstate()
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
39 .map_err(|e| HgError::abort(e.to_string(), exit_codes::ABORT, None))?;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
40 write_tracked_key(repo)
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
41 }
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
42
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
43 /// Update the current working copy of `repo` to the given revision `to`, from
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
44 /// the null revision and set + write out the dirstate to reflect that.
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
45 ///
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
46 /// Do not call this outside of a Python context. This does *not* handle any
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
47 /// of the checks, hooks, lock taking needed to setup and get out of this
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
48 /// update from the null revision.
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
49 pub fn update_from_null(
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
50 repo: &Repo,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
51 to: UncheckedRevision,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
52 progress: &dyn Progress,
52156
e6a44bc91bc2 rust-update: make `update_from_null` respect `worker.numcpu` config option
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52084
diff changeset
53 workers: Option<usize>,
52084
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
54 ) -> Result<usize, HgError> {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
55 // Ignore the warnings, they've been displayed by Python already
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
56 // TODO non-Python clients: display narrow warnings
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
57 let (narrow_matcher, _) = narrow::matcher(repo)?;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
58
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
59 let files_for_rev = list_rev_tracked_files(repo, to, narrow_matcher)
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
60 .map_err(handle_revlog_error)?;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
61 repo.manually_set_parents(DirstateParents {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
62 p1: repo.node(to).expect("update target should exist"),
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
63 p2: NULL_NODE,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
64 })?;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
65
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
66 // Filter the working copy according to the sparse spec
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
67 let tracked_files: Result<Vec<_>, _> = if !repo.has_sparse() {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
68 files_for_rev.iter().collect()
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
69 } else {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
70 // Ignore the warnings, they've been displayed by Python already
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
71 // TODO non-Python clients: display sparse warnings
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
72 let (sparse_matcher, _) = sparse::matcher(repo)?;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
73 files_for_rev
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
74 .iter()
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
75 .filter(|f| {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
76 match f {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
77 Ok(f) => sparse_matcher.matches(f.0),
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
78 Err(_) => true, // Errors stop the update, include them
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
79 }
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
80 })
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
81 .collect()
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
82 };
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
83 let tracked_files = tracked_files?;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
84
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
85 if tracked_files.is_empty() {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
86 // Still write the dirstate because we might not be in the null
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
87 // revision.
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
88 // This can happen in narrow repos where all paths are excluded in
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
89 // this revision.
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
90 write_dirstate(repo)?;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
91 return Ok(0);
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
92 }
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
93 let store_vfs = &repo.store_vfs();
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
94 let options = repo.default_revlog_options(crate::RevlogType::Filelog)?;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
95 let (errors_sender, errors_receiver) = crossbeam_channel::unbounded();
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
96 let (files_sender, files_receiver) = crossbeam_channel::unbounded();
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
97 let working_directory_path = &repo.working_directory_path();
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
98
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
99 let files_count = tracked_files.len();
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
100 let chunks = chunk_tracked_files(tracked_files);
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
101 progress.update(0, Some(files_count as u64));
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
102
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
103 create_working_copy(
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
104 chunks,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
105 working_directory_path,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
106 store_vfs,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
107 options,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
108 files_sender,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
109 errors_sender,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
110 progress,
52156
e6a44bc91bc2 rust-update: make `update_from_null` respect `worker.numcpu` config option
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52084
diff changeset
111 workers,
52084
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
112 );
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
113
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
114 let errors: Vec<HgError> = errors_receiver.iter().collect();
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
115 if !errors.is_empty() {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
116 log::debug!("{} errors during update (see trace logs)", errors.len());
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
117 for error in errors.iter() {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
118 log::trace!("{}", error);
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
119 }
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
120 // Best we can do is raise the first error (in order of the channel)
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
121 return Err(errors.into_iter().next().expect("can never be empty"));
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
122 }
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
123
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
124 // TODO try to run this concurrently to update the dirstate while we're
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
125 // still writing out the working copy to see if that improves performance.
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
126 let total = update_dirstate(repo, files_receiver)?;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
127
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
128 write_dirstate(repo)?;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
129
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
130 Ok(total)
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
131 }
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
132
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
133 fn handle_revlog_error(e: RevlogError) -> HgError {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
134 match e {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
135 crate::RevlogError::Other(hg_error) => hg_error,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
136 e => HgError::abort(
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
137 format!("revlog error: {}", e),
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
138 exit_codes::ABORT,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
139 None,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
140 ),
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
141 }
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
142 }
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
143
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
144 /// Preallocated size of Vec holding directory contents. This aims at
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
145 /// preventing the need for re-allocating the Vec in most cases.
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
146 ///
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
147 /// The value is arbitrarily picked as a little over an average number of files
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
148 /// per directory done by looking at a few larger open-source repos.
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
149 /// Most of the runtime is IO anyway, so this doesn't matter too much.
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
150 const FILES_PER_DIRECTORY: usize = 16;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
151
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
152 /// Chunk files per directory prefix, so almost every directory is handled
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
153 /// in a separate thread, which works around the FS inode mutex.
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
154 /// Chunking less (and doing approximately `files_count`/`threads`) actually
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
155 /// ends up being less performant: my hypothesis is `rayon`'s work stealing
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
156 /// being more efficient with tasks of varying lengths.
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
157 #[logging_timer::time("trace")]
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
158 fn chunk_tracked_files(
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
159 tracked_files: Vec<ExpandedManifestEntry>,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
160 ) -> Vec<(&HgPath, Vec<ExpandedManifestEntry>)> {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
161 let files_count = tracked_files.len();
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
162
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
163 let mut chunks = Vec::with_capacity(files_count / FILES_PER_DIRECTORY);
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
164
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
165 let mut current_chunk = Vec::with_capacity(FILES_PER_DIRECTORY);
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
166 let mut last_directory = tracked_files[0].0.parent();
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
167
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
168 for file_info in tracked_files {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
169 let current_directory = file_info.0.parent();
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
170 let different_directory = current_directory != last_directory;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
171 if different_directory {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
172 chunks.push((last_directory, current_chunk));
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
173 current_chunk = Vec::with_capacity(FILES_PER_DIRECTORY);
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
174 }
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
175 current_chunk.push(file_info);
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
176 last_directory = current_directory;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
177 }
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
178 chunks.push((last_directory, current_chunk));
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
179 chunks
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
180 }
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
181
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
182 #[logging_timer::time("trace")]
52156
e6a44bc91bc2 rust-update: make `update_from_null` respect `worker.numcpu` config option
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52084
diff changeset
183 #[allow(clippy::too_many_arguments)]
52084
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
184 fn create_working_copy<'a: 'b, 'b>(
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
185 chunks: Vec<(&HgPath, Vec<ExpandedManifestEntry<'a>>)>,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
186 working_directory_path: &Path,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
187 store_vfs: &VfsImpl,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
188 options: RevlogOpenOptions,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
189 files_sender: Sender<(&'b HgPath, u32, usize, TruncatedTimestamp)>,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
190 error_sender: Sender<HgError>,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
191 progress: &dyn Progress,
52156
e6a44bc91bc2 rust-update: make `update_from_null` respect `worker.numcpu` config option
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52084
diff changeset
192 workers: Option<usize>,
52084
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
193 ) {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
194 let auditor = PathAuditor::new(working_directory_path);
52156
e6a44bc91bc2 rust-update: make `update_from_null` respect `worker.numcpu` config option
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52084
diff changeset
195 let work_closure = |(dir_path, chunk)| {
52084
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
196 if let Err(e) = working_copy_worker(
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
197 dir_path,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
198 chunk,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
199 working_directory_path,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
200 store_vfs,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
201 options,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
202 &files_sender,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
203 progress,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
204 &auditor,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
205 ) {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
206 error_sender
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
207 .send(e)
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
208 .expect("channel should not be disconnected")
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
209 }
52156
e6a44bc91bc2 rust-update: make `update_from_null` respect `worker.numcpu` config option
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52084
diff changeset
210 };
e6a44bc91bc2 rust-update: make `update_from_null` respect `worker.numcpu` config option
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52084
diff changeset
211 if let Some(workers) = workers {
e6a44bc91bc2 rust-update: make `update_from_null` respect `worker.numcpu` config option
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52084
diff changeset
212 if workers > 1 {
e6a44bc91bc2 rust-update: make `update_from_null` respect `worker.numcpu` config option
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52084
diff changeset
213 // Work in parallel, potentially restricting the number of threads
e6a44bc91bc2 rust-update: make `update_from_null` respect `worker.numcpu` config option
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52084
diff changeset
214 match rayon::ThreadPoolBuilder::new().num_threads(workers).build()
e6a44bc91bc2 rust-update: make `update_from_null` respect `worker.numcpu` config option
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52084
diff changeset
215 {
e6a44bc91bc2 rust-update: make `update_from_null` respect `worker.numcpu` config option
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52084
diff changeset
216 Err(error) => error_sender
e6a44bc91bc2 rust-update: make `update_from_null` respect `worker.numcpu` config option
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52084
diff changeset
217 .send(HgError::abort(
e6a44bc91bc2 rust-update: make `update_from_null` respect `worker.numcpu` config option
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52084
diff changeset
218 error.to_string(),
e6a44bc91bc2 rust-update: make `update_from_null` respect `worker.numcpu` config option
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52084
diff changeset
219 exit_codes::ABORT,
e6a44bc91bc2 rust-update: make `update_from_null` respect `worker.numcpu` config option
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52084
diff changeset
220 None,
e6a44bc91bc2 rust-update: make `update_from_null` respect `worker.numcpu` config option
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52084
diff changeset
221 ))
e6a44bc91bc2 rust-update: make `update_from_null` respect `worker.numcpu` config option
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52084
diff changeset
222 .expect("channel should not be disconnected"),
e6a44bc91bc2 rust-update: make `update_from_null` respect `worker.numcpu` config option
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52084
diff changeset
223 Ok(pool) => {
e6a44bc91bc2 rust-update: make `update_from_null` respect `worker.numcpu` config option
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52084
diff changeset
224 log::trace!("restricting update to {} threads", workers);
e6a44bc91bc2 rust-update: make `update_from_null` respect `worker.numcpu` config option
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52084
diff changeset
225 pool.install(|| {
e6a44bc91bc2 rust-update: make `update_from_null` respect `worker.numcpu` config option
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52084
diff changeset
226 chunks.into_par_iter().for_each(work_closure);
e6a44bc91bc2 rust-update: make `update_from_null` respect `worker.numcpu` config option
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52084
diff changeset
227 });
e6a44bc91bc2 rust-update: make `update_from_null` respect `worker.numcpu` config option
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52084
diff changeset
228 }
e6a44bc91bc2 rust-update: make `update_from_null` respect `worker.numcpu` config option
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52084
diff changeset
229 }
e6a44bc91bc2 rust-update: make `update_from_null` respect `worker.numcpu` config option
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52084
diff changeset
230 } else {
e6a44bc91bc2 rust-update: make `update_from_null` respect `worker.numcpu` config option
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52084
diff changeset
231 // Work sequentially, don't even invoke rayon
e6a44bc91bc2 rust-update: make `update_from_null` respect `worker.numcpu` config option
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52084
diff changeset
232 chunks.into_iter().for_each(work_closure);
e6a44bc91bc2 rust-update: make `update_from_null` respect `worker.numcpu` config option
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52084
diff changeset
233 }
e6a44bc91bc2 rust-update: make `update_from_null` respect `worker.numcpu` config option
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52084
diff changeset
234 } else {
e6a44bc91bc2 rust-update: make `update_from_null` respect `worker.numcpu` config option
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52084
diff changeset
235 // Work in parallel by default in the global threadpool
e6a44bc91bc2 rust-update: make `update_from_null` respect `worker.numcpu` config option
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52084
diff changeset
236 let _ = cap_default_rayon_threads();
e6a44bc91bc2 rust-update: make `update_from_null` respect `worker.numcpu` config option
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52084
diff changeset
237 chunks.into_par_iter().for_each(work_closure);
e6a44bc91bc2 rust-update: make `update_from_null` respect `worker.numcpu` config option
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52084
diff changeset
238 }
52084
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
239 }
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
240
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
241 /// Represents a work unit for a single thread, responsible for this set of
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
242 /// files and restoring them to the working copy.
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
243 #[allow(clippy::too_many_arguments)]
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
244 fn working_copy_worker<'a: 'b, 'b>(
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
245 dir_path: &HgPath,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
246 chunk: Vec<ExpandedManifestEntry<'a>>,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
247 working_directory_path: &Path,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
248 store_vfs: &VfsImpl,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
249 options: RevlogOpenOptions,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
250 files_sender: &Sender<(&'b HgPath, u32, usize, TruncatedTimestamp)>,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
251 progress: &dyn Progress,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
252 auditor: &PathAuditor,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
253 ) -> Result<(), HgError> {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
254 let dir_path =
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
255 hg_path_to_path_buf(dir_path).expect("invalid path in manifest");
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
256 let dir_path = working_directory_path.join(dir_path);
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
257 std::fs::create_dir_all(&dir_path).when_writing_file(&dir_path)?;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
258
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
259 for (file, file_node, flags) in chunk {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
260 auditor.audit_path(file)?;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
261 let flags = flags.map(|f| f.into());
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
262 let path =
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
263 working_directory_path.join(get_path_from_bytes(file.as_bytes()));
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
264
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
265 // Treemanifest is not supported
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
266 assert!(flags != Some(b't'));
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
267
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
268 let filelog = Filelog::open_vfs(store_vfs, file, options)?;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
269 let filelog_revision_data = &filelog
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
270 .data_for_node(file_node)
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
271 .map_err(handle_revlog_error)?;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
272 let file_data = filelog_revision_data.file_data()?;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
273
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
274 if flags == Some(b'l') {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
275 let target = get_path_from_bytes(file_data);
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
276 if let Err(e) = std::os::unix::fs::symlink(target, &path) {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
277 // If the path already exists either:
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
278 // - another process created this file while ignoring the
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
279 // lock => error
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
280 // - our check for the fast path is incorrect => error
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
281 // - this is a malicious repo/bundle and this is symlink that
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
282 // tries to write things where it shouldn't be able to.
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
283 match e.kind() {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
284 std::io::ErrorKind::AlreadyExists => {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
285 let metadata = std::fs::symlink_metadata(&path)
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
286 .when_reading_file(&path)?;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
287 if metadata.is_dir() {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
288 return Err(HgError::Path(
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
289 HgPathError::TraversesSymbolicLink {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
290 // Technically it should be one of the
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
291 // children, but good enough
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
292 path: file
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
293 .join(HgPath::new(b"*"))
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
294 .to_owned(),
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
295 symlink: file.to_owned(),
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
296 },
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
297 ));
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
298 }
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
299 return Err(e).when_writing_file(&path);
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
300 }
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
301 _ => return Err(e).when_writing_file(&path),
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
302 }
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
303 }
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
304 } else {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
305 let mut f =
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
306 std::fs::File::create(&path).when_writing_file(&path)?;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
307 f.write_all(file_data).when_writing_file(&path)?;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
308 }
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
309 if flags == Some(b'x') {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
310 std::fs::set_permissions(&path, Permissions::from_mode(0o755))
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
311 .when_writing_file(&path)?;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
312 }
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
313 let metadata =
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
314 std::fs::symlink_metadata(&path).when_reading_file(&path)?;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
315
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
316 let mode = metadata.mode();
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
317
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
318 files_sender
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
319 .send((
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
320 file,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
321 mode,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
322 file_data.len(),
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
323 TruncatedTimestamp::for_mtime_of(&metadata)
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
324 .when_reading_file(&path)?,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
325 ))
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
326 .expect("channel should not be closed");
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
327 progress.increment(1, None);
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
328 }
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
329 Ok(())
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
330 }
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
331
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
332 #[logging_timer::time("trace")]
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
333 fn update_dirstate(
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
334 repo: &Repo,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
335 files_receiver: Receiver<(&HgPath, u32, usize, TruncatedTimestamp)>,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
336 ) -> Result<usize, HgError> {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
337 let mut dirstate = repo
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
338 .dirstate_map_mut()
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
339 .map_err(|e| HgError::abort(e.to_string(), exit_codes::ABORT, None))?;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
340
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
341 // (see the comments in `filter_ambiguous_files` in `merge.py` for more)
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
342 // It turns out that (on Linux at least) the filesystem resolution time
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
343 // for most filesystems is based on the HZ kernel config. Their internal
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
344 // clocks do return nanoseconds if the hardware clock is precise enough,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
345 // which should be the case on most recent computers but are only updated
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
346 // every few milliseconds at best (every "jiffy").
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
347 //
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
348 // We are still not concerned with fixing the race with other
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
349 // processes that might modify the working copy right after it was created
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
350 // within the same tick, because it is impossible to catch.
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
351 // However, we might as well not race with operations that could run right
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
352 // after this one, especially other Mercurial operations that could be
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
353 // waiting for the wlock to change file contents and the dirstate.
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
354 //
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
355 // Thus: wait until the filesystem clock has ticked to filter ambiguous
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
356 // entries and write the dirstate, but only for dirstate-v2, since v1 only
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
357 // has second-level granularity and waiting for a whole second is too much
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
358 // of a penalty in the general case.
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
359 // Although we're assuming that people running dirstate-v2 on Linux
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
360 // don't have a second-granularity FS (with the exclusion of NFS), users
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
361 // can be surprising, and at some point in the future dirstate-v2 will
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
362 // become the default. To that end, we limit the wait time to 100ms and
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
363 // fall back to the filter method in case of a timeout.
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
364 //
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
365 // +------------+------+--------------+
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
366 // | version | wait | filter level |
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
367 // +------------+------+--------------+
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
368 // | V1 | No | Second |
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
369 // | V2 | Yes | Nanosecond |
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
370 // | V2-slow-fs | No | Second |
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
371 // +------------+------+--------------+
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
372 let dirstate_v2 = repo.use_dirstate_v2();
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
373
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
374 // Let's ignore NFS right off the bat
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
375 let mut fast_enough_fs = !is_on_nfs_mount(repo.working_directory_path());
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
376 let fs_time_now = if dirstate_v2 && fast_enough_fs {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
377 match wait_until_fs_tick(repo.working_directory_path()) {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
378 None => None,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
379 Some(Ok(time)) => Some(time),
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
380 Some(Err(time)) => {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
381 fast_enough_fs = false;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
382 Some(time)
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
383 }
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
384 }
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
385 } else {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
386 filesystem_now(repo.working_directory_path())
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
387 .ok()
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
388 .map(TruncatedTimestamp::from)
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
389 };
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
390
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
391 let mut total = 0;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
392 for (filename, mode, size, mtime) in files_receiver.into_iter() {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
393 total += 1;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
394 // When using dirstate-v2 on a filesystem with reasonable performance
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
395 // this is basically always true unless you get a mtime from the
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
396 // far future.
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
397 let has_meaningful_mtime = if let Some(fs_time) = fs_time_now {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
398 mtime.for_reliable_mtime_of_self(&fs_time).is_some_and(|t| {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
399 // Dirstate-v1 only has second-level information
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
400 !t.second_ambiguous || dirstate_v2 && fast_enough_fs
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
401 })
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
402 } else {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
403 // We somehow failed to write to the filesystem, so don't store
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
404 // the cache information.
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
405 false
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
406 };
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
407 let reset = DirstateEntryReset {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
408 filename,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
409 wc_tracked: true,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
410 p1_tracked: true,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
411 p2_info: false,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
412 has_meaningful_mtime,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
413 parent_file_data_opt: Some(ParentFileData {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
414 mode_size: Some((
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
415 mode,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
416 size.try_into().expect("invalid file size in manifest"),
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
417 )),
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
418 mtime: Some(mtime),
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
419 }),
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
420 from_empty: true,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
421 };
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
422 dirstate.reset_state(reset).map_err(|e| {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
423 HgError::abort(e.to_string(), exit_codes::ABORT, None)
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
424 })?;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
425 }
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
426
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
427 Ok(total)
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
428 }
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
429
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
430 /// Wait until the next update from the filesystem time by writing in a loop
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
431 /// a new temporary file inside the working directory and checking if its time
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
432 /// differs from the first one observed.
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
433 ///
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
434 /// Returns `None` if we are unable to get the filesystem time,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
435 /// `Some(Err(timestamp))` if we've timed out waiting for the filesystem clock
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
436 /// to tick, and `Some(Ok(timestamp))` if we've waited successfully.
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
437 ///
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
438 /// On Linux, your average tick is going to be a "jiffy", or 1/HZ.
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
439 /// HZ is your kernel's tick rate (if it has one configured) and the value
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
440 /// is the one returned by `grep 'CONFIG_HZ=' /boot/config-$(uname -r)`,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
441 /// again assuming a normal setup.
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
442 ///
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
443 /// In my case (Alphare) at the time of writing, I get `CONFIG_HZ=250`,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
444 /// which equates to 4ms.
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
445 ///
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
446 /// This might change with a series that could make it to Linux 6.12:
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
447 /// https://lore.kernel.org/all/20241002-mgtime-v10-8-d1c4717f5284@kernel.org
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
448 fn wait_until_fs_tick(
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
449 working_directory_path: &Path,
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
450 ) -> Option<Result<TruncatedTimestamp, TruncatedTimestamp>> {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
451 let start = std::time::Instant::now();
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
452 let old_fs_time = filesystem_now(working_directory_path).ok()?;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
453 let mut fs_time = filesystem_now(working_directory_path).ok()?;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
454
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
455 const FS_TICK_WAIT_TIMEOUT: Duration = Duration::from_millis(100);
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
456
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
457 while fs_time == old_fs_time {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
458 if std::time::Instant::now() - start > FS_TICK_WAIT_TIMEOUT {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
459 log::trace!(
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
460 "timed out waiting for the fs clock to tick after {:?}",
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
461 FS_TICK_WAIT_TIMEOUT
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
462 );
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
463 return Some(Err(TruncatedTimestamp::from(old_fs_time)));
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
464 }
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
465 fs_time = filesystem_now(working_directory_path).ok()?;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
466 }
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
467 log::trace!(
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
468 "waited for {:?} before writing the dirstate",
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
469 fs_time.duration_since(old_fs_time)
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
470 );
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
471 Some(Ok(TruncatedTimestamp::from(fs_time)))
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
472 }
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
473
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
474 #[cfg(test)]
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
475 mod test {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
476 use super::*;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
477 use pretty_assertions::assert_eq;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
478
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
479 #[test]
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
480 fn test_chunk_tracked_files() {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
481 fn chunk(v: Vec<&'static str>) -> Vec<ExpandedManifestEntry> {
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
482 v.into_iter()
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
483 .map(|f| (HgPath::new(f.as_bytes()), NULL_NODE, None))
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
484 .collect()
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
485 }
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
486 let p = HgPath::new;
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
487
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
488 let files = chunk(vec!["a"]);
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
489 let expected = vec![(p(""), chunk(vec!["a"]))];
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
490 assert_eq!(chunk_tracked_files(files), expected);
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
491
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
492 let files = chunk(vec!["a", "b", "c"]);
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
493 let expected = vec![(p(""), chunk(vec!["a", "b", "c"]))];
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
494 assert_eq!(chunk_tracked_files(files), expected);
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
495
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
496 let files = chunk(vec![
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
497 "dir/a-new",
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
498 "dir/a/mut",
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
499 "dir/a/mut-mut",
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
500 "dir/albert",
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
501 "dir/b",
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
502 "dir/subdir/c",
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
503 "dir/subdir/d",
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
504 "file",
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
505 ]);
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
506 let expected = vec![
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
507 (p("dir"), chunk(vec!["dir/a-new"])),
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
508 (p("dir/a"), chunk(vec!["dir/a/mut", "dir/a/mut-mut"])),
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
509 (p("dir"), chunk(vec!["dir/albert", "dir/b"])),
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
510 (p("dir/subdir"), chunk(vec!["dir/subdir/c", "dir/subdir/d"])),
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
511 (p(""), chunk(vec!["file"])),
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
512 ];
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
513 assert_eq!(chunk_tracked_files(files), expected);
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
514
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
515 // Doesn't get split
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
516 let large_dir = vec![
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
517 "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12",
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
518 "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23",
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
519 ];
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
520 let files = chunk(large_dir.clone());
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
521 let expected = vec![(p(""), chunk(large_dir))];
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
522 assert_eq!(chunk_tracked_files(files), expected);
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
523 }
8b7123c8947b update: add a Rust fast-path when updating from null (and clean)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
524 }