Mercurial > hg
annotate rust/hg-core/src/repo.rs @ 50211:f5e4248e5bce stable
dirstate: add some debug output when writing the dirstate
This helps debugging Mercurial behavior in the dirstate-v2 case.
author | Raphaël Gomès <rgomes@octobus.net> |
---|---|
date | Tue, 28 Feb 2023 00:04:32 +0100 |
parents | be019ac8c1e4 |
children | 1891086f6c7f |
rev | line source |
---|---|
47959
21d25e9ee58e
rust: Keep lazily-initialized Changelog and Manifest log on the Repo object
Simon Sapin <simon.sapin@octobus.net>
parents:
47958
diff
changeset
|
1 use crate::changelog::Changelog; |
46486
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
2 use crate::config::{Config, ConfigError, ConfigParseError}; |
47956
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
3 use crate::dirstate::DirstateParents; |
48421
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
4 use crate::dirstate_tree::on_disk::Docket as DirstateDocket; |
47956
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
5 use crate::dirstate_tree::owning::OwningDirstateMap; |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
6 use crate::errors::HgResultExt; |
48421
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
7 use crate::errors::{HgError, IoResultExt}; |
48417
5734b03ecf3e
rhg: Initial repository locking
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
8 use crate::lock::{try_with_lock_no_wait, LockError}; |
47960
cfb6e6699b25
rust: Add Repo::manifest(revision)
Simon Sapin <simon.sapin@octobus.net>
parents:
47959
diff
changeset
|
9 use crate::manifest::{Manifest, Manifestlog}; |
47961
4d2a5ca060e3
rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
47960
diff
changeset
|
10 use crate::revlog::filelog::Filelog; |
47959
21d25e9ee58e
rust: Keep lazily-initialized Changelog and Manifest log on the Repo object
Simon Sapin <simon.sapin@octobus.net>
parents:
47958
diff
changeset
|
11 use crate::revlog::revlog::RevlogError; |
46462
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
12 use crate::utils::files::get_path_from_bytes; |
47961
4d2a5ca060e3
rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
47960
diff
changeset
|
13 use crate::utils::hg_path::HgPath; |
46740
97ac588b6d9e
rhg: Don’t make repository path absolute too early
Simon Sapin <simon.sapin@octobus.net>
parents:
46735
diff
changeset
|
14 use crate::utils::SliceExt; |
47952
9cd35c8c6044
rust: Move VFS code to its own module
Simon Sapin <simon.sapin@octobus.net>
parents:
47949
diff
changeset
|
15 use crate::vfs::{is_dir, is_file, Vfs}; |
47964
796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents:
47963
diff
changeset
|
16 use crate::{requirements, NodePrefix}; |
47960
cfb6e6699b25
rust: Add Repo::manifest(revision)
Simon Sapin <simon.sapin@octobus.net>
parents:
47959
diff
changeset
|
17 use crate::{DirstateError, Revision}; |
48419
c8659e61073d
rhg: Make Repo::dirstate_parents a LazyCell
Simon Sapin <simon.sapin@octobus.net>
parents:
48417
diff
changeset
|
18 use std::cell::{Ref, RefCell, RefMut}; |
46462
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
19 use std::collections::HashSet; |
48421
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
20 use std::io::Seek; |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
21 use std::io::SeekFrom; |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
22 use std::io::Write as IoWrite; |
46167
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
23 use std::path::{Path, PathBuf}; |
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
24 |
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
25 /// A repository on disk |
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
26 pub struct Repo { |
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
27 working_directory: PathBuf, |
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
28 dot_hg: PathBuf, |
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
29 store: PathBuf, |
46462
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
30 requirements: HashSet<String>, |
46486
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
31 config: Config, |
49177
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
32 dirstate_parents: LazyCell<DirstateParents>, |
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
33 dirstate_data_file_uuid: LazyCell<Option<Vec<u8>>>, |
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
34 dirstate_map: LazyCell<OwningDirstateMap>, |
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
35 changelog: LazyCell<Changelog>, |
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
36 manifestlog: LazyCell<Manifestlog>, |
46167
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
37 } |
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
38 |
46446
1dcd9c9975ed
rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents:
46443
diff
changeset
|
39 #[derive(Debug, derive_more::From)] |
46486
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
40 pub enum RepoError { |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
41 NotFound { |
46503
d8730ff51d5a
rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
42 at: PathBuf, |
46446
1dcd9c9975ed
rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents:
46443
diff
changeset
|
43 }, |
1dcd9c9975ed
rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents:
46443
diff
changeset
|
44 #[from] |
46486
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
45 ConfigParseError(ConfigParseError), |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
46 #[from] |
46446
1dcd9c9975ed
rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents:
46443
diff
changeset
|
47 Other(HgError), |
1dcd9c9975ed
rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents:
46443
diff
changeset
|
48 } |
1dcd9c9975ed
rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents:
46443
diff
changeset
|
49 |
46486
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
50 impl From<ConfigError> for RepoError { |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
51 fn from(error: ConfigError) -> Self { |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
52 match error { |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
53 ConfigError::Parse(error) => error.into(), |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
54 ConfigError::Other(error) => error.into(), |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
55 } |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
56 } |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
57 } |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
58 |
46167
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
59 impl Repo { |
47405
88119fffecc8
rhg: look for repository in ancestors also instead of cwd only
Pulkit Goyal <7895pulkit@gmail.com>
parents:
47404
diff
changeset
|
60 /// tries to find nearest repository root in current working directory or |
88119fffecc8
rhg: look for repository in ancestors also instead of cwd only
Pulkit Goyal <7895pulkit@gmail.com>
parents:
47404
diff
changeset
|
61 /// its ancestors |
88119fffecc8
rhg: look for repository in ancestors also instead of cwd only
Pulkit Goyal <7895pulkit@gmail.com>
parents:
47404
diff
changeset
|
62 pub fn find_repo_root() -> Result<PathBuf, RepoError> { |
88119fffecc8
rhg: look for repository in ancestors also instead of cwd only
Pulkit Goyal <7895pulkit@gmail.com>
parents:
47404
diff
changeset
|
63 let current_directory = crate::utils::current_dir()?; |
88119fffecc8
rhg: look for repository in ancestors also instead of cwd only
Pulkit Goyal <7895pulkit@gmail.com>
parents:
47404
diff
changeset
|
64 // ancestors() is inclusive: it first yields `current_directory` |
88119fffecc8
rhg: look for repository in ancestors also instead of cwd only
Pulkit Goyal <7895pulkit@gmail.com>
parents:
47404
diff
changeset
|
65 // as-is. |
88119fffecc8
rhg: look for repository in ancestors also instead of cwd only
Pulkit Goyal <7895pulkit@gmail.com>
parents:
47404
diff
changeset
|
66 for ancestor in current_directory.ancestors() { |
47780
cf5f8da2244c
rhg: Propagate permission errors when finding a repository
Simon Sapin <simon.sapin@octobus.net>
parents:
47674
diff
changeset
|
67 if is_dir(ancestor.join(".hg"))? { |
47405
88119fffecc8
rhg: look for repository in ancestors also instead of cwd only
Pulkit Goyal <7895pulkit@gmail.com>
parents:
47404
diff
changeset
|
68 return Ok(ancestor.to_path_buf()); |
88119fffecc8
rhg: look for repository in ancestors also instead of cwd only
Pulkit Goyal <7895pulkit@gmail.com>
parents:
47404
diff
changeset
|
69 } |
88119fffecc8
rhg: look for repository in ancestors also instead of cwd only
Pulkit Goyal <7895pulkit@gmail.com>
parents:
47404
diff
changeset
|
70 } |
88119fffecc8
rhg: look for repository in ancestors also instead of cwd only
Pulkit Goyal <7895pulkit@gmail.com>
parents:
47404
diff
changeset
|
71 return Err(RepoError::NotFound { |
88119fffecc8
rhg: look for repository in ancestors also instead of cwd only
Pulkit Goyal <7895pulkit@gmail.com>
parents:
47404
diff
changeset
|
72 at: current_directory, |
88119fffecc8
rhg: look for repository in ancestors also instead of cwd only
Pulkit Goyal <7895pulkit@gmail.com>
parents:
47404
diff
changeset
|
73 }); |
88119fffecc8
rhg: look for repository in ancestors also instead of cwd only
Pulkit Goyal <7895pulkit@gmail.com>
parents:
47404
diff
changeset
|
74 } |
88119fffecc8
rhg: look for repository in ancestors also instead of cwd only
Pulkit Goyal <7895pulkit@gmail.com>
parents:
47404
diff
changeset
|
75 |
46505
a25033eb43b5
rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents:
46503
diff
changeset
|
76 /// Find a repository, either at the given path (which must contain a `.hg` |
a25033eb43b5
rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents:
46503
diff
changeset
|
77 /// sub-directory) or by searching the current directory and its |
a25033eb43b5
rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents:
46503
diff
changeset
|
78 /// ancestors. |
46503
d8730ff51d5a
rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
79 /// |
46505
a25033eb43b5
rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents:
46503
diff
changeset
|
80 /// A method with two very different "modes" like this usually a code smell |
a25033eb43b5
rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents:
46503
diff
changeset
|
81 /// to make two methods instead, but in this case an `Option` is what rhg |
a25033eb43b5
rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents:
46503
diff
changeset
|
82 /// sub-commands get from Clap for the `-R` / `--repository` CLI argument. |
a25033eb43b5
rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents:
46503
diff
changeset
|
83 /// Having two methods would just move that `if` to almost all callers. |
46503
d8730ff51d5a
rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
84 pub fn find( |
d8730ff51d5a
rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
85 config: &Config, |
47404
ebdef6283798
rhg: read [paths] for `--repository` value
Pulkit Goyal <7895pulkit@gmail.com>
parents:
47374
diff
changeset
|
86 explicit_path: Option<PathBuf>, |
46503
d8730ff51d5a
rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
87 ) -> Result<Self, RepoError> { |
d8730ff51d5a
rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
88 if let Some(root) = explicit_path { |
47780
cf5f8da2244c
rhg: Propagate permission errors when finding a repository
Simon Sapin <simon.sapin@octobus.net>
parents:
47674
diff
changeset
|
89 if is_dir(root.join(".hg"))? { |
46740
97ac588b6d9e
rhg: Don’t make repository path absolute too early
Simon Sapin <simon.sapin@octobus.net>
parents:
46735
diff
changeset
|
90 Self::new_at_path(root.to_owned(), config) |
47780
cf5f8da2244c
rhg: Propagate permission errors when finding a repository
Simon Sapin <simon.sapin@octobus.net>
parents:
47674
diff
changeset
|
91 } else if is_file(&root)? { |
46730
dfd35823635b
rhg: Fall back to Python for bundle repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46728
diff
changeset
|
92 Err(HgError::unsupported("bundle repository").into()) |
46503
d8730ff51d5a
rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
93 } else { |
d8730ff51d5a
rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
94 Err(RepoError::NotFound { |
d8730ff51d5a
rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
95 at: root.to_owned(), |
d8730ff51d5a
rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
96 }) |
46446
1dcd9c9975ed
rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents:
46443
diff
changeset
|
97 } |
46503
d8730ff51d5a
rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
98 } else { |
47405
88119fffecc8
rhg: look for repository in ancestors also instead of cwd only
Pulkit Goyal <7895pulkit@gmail.com>
parents:
47404
diff
changeset
|
99 let root = Self::find_repo_root()?; |
88119fffecc8
rhg: look for repository in ancestors also instead of cwd only
Pulkit Goyal <7895pulkit@gmail.com>
parents:
47404
diff
changeset
|
100 Self::new_at_path(root, config) |
46167
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
101 } |
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
102 } |
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
103 |
46462
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
104 /// To be called after checking that `.hg` is a sub-directory |
46485
f031fe1c6ede
rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents:
46484
diff
changeset
|
105 fn new_at_path( |
f031fe1c6ede
rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents:
46484
diff
changeset
|
106 working_directory: PathBuf, |
f031fe1c6ede
rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents:
46484
diff
changeset
|
107 config: &Config, |
46486
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
108 ) -> Result<Self, RepoError> { |
46462
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
109 let dot_hg = working_directory.join(".hg"); |
46463
95b276283b67
rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents:
46462
diff
changeset
|
110 |
46486
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
111 let mut repo_config_files = Vec::new(); |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
112 repo_config_files.push(dot_hg.join("hgrc")); |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
113 repo_config_files.push(dot_hg.join("hgrc-not-shared")); |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
114 |
46462
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
115 let hg_vfs = Vfs { base: &dot_hg }; |
46463
95b276283b67
rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents:
46462
diff
changeset
|
116 let mut reqs = requirements::load_if_exists(hg_vfs)?; |
46462
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
117 let relative = |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
118 reqs.contains(requirements::RELATIVE_SHARED_REQUIREMENT); |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
119 let shared = |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
120 reqs.contains(requirements::SHARED_REQUIREMENT) || relative; |
46463
95b276283b67
rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents:
46462
diff
changeset
|
121 |
95b276283b67
rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents:
46462
diff
changeset
|
122 // From `mercurial/localrepo.py`: |
95b276283b67
rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents:
46462
diff
changeset
|
123 // |
95b276283b67
rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents:
46462
diff
changeset
|
124 // if .hg/requires contains the sharesafe requirement, it means |
95b276283b67
rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents:
46462
diff
changeset
|
125 // there exists a `.hg/store/requires` too and we should read it |
95b276283b67
rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents:
46462
diff
changeset
|
126 // NOTE: presence of SHARESAFE_REQUIREMENT imply that store requirement |
95b276283b67
rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents:
46462
diff
changeset
|
127 // is present. We never write SHARESAFE_REQUIREMENT for a repo if store |
95b276283b67
rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents:
46462
diff
changeset
|
128 // is not present, refer checkrequirementscompat() for that |
95b276283b67
rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents:
46462
diff
changeset
|
129 // |
95b276283b67
rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents:
46462
diff
changeset
|
130 // However, if SHARESAFE_REQUIREMENT is not present, it means that the |
95b276283b67
rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents:
46462
diff
changeset
|
131 // repository was shared the old way. We check the share source |
95b276283b67
rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents:
46462
diff
changeset
|
132 // .hg/requires for SHARESAFE_REQUIREMENT to detect whether the |
95b276283b67
rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents:
46462
diff
changeset
|
133 // current repository needs to be reshared |
95b276283b67
rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents:
46462
diff
changeset
|
134 let share_safe = reqs.contains(requirements::SHARESAFE_REQUIREMENT); |
95b276283b67
rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents:
46462
diff
changeset
|
135 |
46462
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
136 let store_path; |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
137 if !shared { |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
138 store_path = dot_hg.join("store"); |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
139 } else { |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
140 let bytes = hg_vfs.read("sharedpath")?; |
46669
e8cd519a0a34
rhg: Ignore trailing newlines in .hg/sharedpath
Simon Sapin <simon.sapin@octobus.net>
parents:
46613
diff
changeset
|
141 let mut shared_path = |
47949
696abab107b4
rust: Generalize the `trim_end_newlines` utility of byte strings
Simon Sapin <simon.sapin@octobus.net>
parents:
47780
diff
changeset
|
142 get_path_from_bytes(bytes.trim_end_matches(|b| b == b'\n')) |
696abab107b4
rust: Generalize the `trim_end_newlines` utility of byte strings
Simon Sapin <simon.sapin@octobus.net>
parents:
47780
diff
changeset
|
143 .to_owned(); |
46462
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
144 if relative { |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
145 shared_path = dot_hg.join(shared_path) |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
146 } |
47780
cf5f8da2244c
rhg: Propagate permission errors when finding a repository
Simon Sapin <simon.sapin@octobus.net>
parents:
47674
diff
changeset
|
147 if !is_dir(&shared_path)? { |
46462
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
148 return Err(HgError::corrupted(format!( |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
149 ".hg/sharedpath points to nonexistent directory {}", |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
150 shared_path.display() |
46486
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
151 )) |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
152 .into()); |
46462
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
153 } |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
154 |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
155 store_path = shared_path.join("store"); |
46463
95b276283b67
rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents:
46462
diff
changeset
|
156 |
95b276283b67
rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents:
46462
diff
changeset
|
157 let source_is_share_safe = |
95b276283b67
rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents:
46462
diff
changeset
|
158 requirements::load(Vfs { base: &shared_path })? |
95b276283b67
rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents:
46462
diff
changeset
|
159 .contains(requirements::SHARESAFE_REQUIREMENT); |
95b276283b67
rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents:
46462
diff
changeset
|
160 |
48809
1d5fd9def5ac
rhg: simplify the handling of share-safe config mismatch
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48510
diff
changeset
|
161 if share_safe != source_is_share_safe { |
1d5fd9def5ac
rhg: simplify the handling of share-safe config mismatch
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48510
diff
changeset
|
162 return Err(HgError::unsupported("share-safe mismatch").into()); |
46463
95b276283b67
rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents:
46462
diff
changeset
|
163 } |
46486
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
164 |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
165 if share_safe { |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
166 repo_config_files.insert(0, shared_path.join("hgrc")) |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
167 } |
46462
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
168 } |
46613
f64b6953db70
rhg: Bug fix: with share-safe, always read store requirements
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
169 if share_safe { |
f64b6953db70
rhg: Bug fix: with share-safe, always read store requirements
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
170 reqs.extend(requirements::load(Vfs { base: &store_path })?); |
f64b6953db70
rhg: Bug fix: with share-safe, always read store requirements
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
171 } |
46462
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
172 |
46741
25e3dac511f0
rhg: Add support for the HGRCSKIPREPO environment variable
Simon Sapin <simon.sapin@octobus.net>
parents:
46740
diff
changeset
|
173 let repo_config = if std::env::var_os("HGRCSKIPREPO").is_none() { |
25e3dac511f0
rhg: Add support for the HGRCSKIPREPO environment variable
Simon Sapin <simon.sapin@octobus.net>
parents:
46740
diff
changeset
|
174 config.combine_with_repo(&repo_config_files)? |
25e3dac511f0
rhg: Add support for the HGRCSKIPREPO environment variable
Simon Sapin <simon.sapin@octobus.net>
parents:
46740
diff
changeset
|
175 } else { |
25e3dac511f0
rhg: Add support for the HGRCSKIPREPO environment variable
Simon Sapin <simon.sapin@octobus.net>
parents:
46740
diff
changeset
|
176 config.clone() |
25e3dac511f0
rhg: Add support for the HGRCSKIPREPO environment variable
Simon Sapin <simon.sapin@octobus.net>
parents:
46740
diff
changeset
|
177 }; |
46486
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
178 |
46462
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
179 let repo = Self { |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
180 requirements: reqs, |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
181 working_directory, |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
182 store: store_path, |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
183 dot_hg, |
46486
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
184 config: repo_config, |
49177
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
185 dirstate_parents: LazyCell::new(), |
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
186 dirstate_data_file_uuid: LazyCell::new(), |
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
187 dirstate_map: LazyCell::new(), |
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
188 changelog: LazyCell::new(), |
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
189 manifestlog: LazyCell::new(), |
46462
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
190 }; |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
191 |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
192 requirements::check(&repo)?; |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
193 |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
194 Ok(repo) |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
195 } |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
196 |
46167
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
197 pub fn working_directory_path(&self) -> &Path { |
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
198 &self.working_directory |
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
199 } |
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
200 |
46462
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
201 pub fn requirements(&self) -> &HashSet<String> { |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
202 &self.requirements |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
203 } |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
204 |
46486
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
205 pub fn config(&self) -> &Config { |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
206 &self.config |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
207 } |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
208 |
46167
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
209 /// For accessing repository files (in `.hg`), except for the store |
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
210 /// (`.hg/store`). |
46599
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46593
diff
changeset
|
211 pub fn hg_vfs(&self) -> Vfs<'_> { |
46167
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
212 Vfs { base: &self.dot_hg } |
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
213 } |
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
214 |
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
215 /// For accessing repository store files (in `.hg/store`) |
46599
1f55cd5b292f
rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents:
46593
diff
changeset
|
216 pub fn store_vfs(&self) -> Vfs<'_> { |
46167
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
217 Vfs { base: &self.store } |
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
218 } |
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
219 |
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
220 /// For accessing the working copy |
46822
c71e8d9e7f2a
rhg: Initial support for the 'status' command
Georges Racinet <georges.racinet@octobus.net>
parents:
46741
diff
changeset
|
221 pub fn working_directory_vfs(&self) -> Vfs<'_> { |
46167
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
222 Vfs { |
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
223 base: &self.working_directory, |
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
224 } |
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
225 } |
46601
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46599
diff
changeset
|
226 |
48417
5734b03ecf3e
rhg: Initial repository locking
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
227 pub fn try_with_wlock_no_wait<R>( |
5734b03ecf3e
rhg: Initial repository locking
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
228 &self, |
5734b03ecf3e
rhg: Initial repository locking
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
229 f: impl FnOnce() -> R, |
5734b03ecf3e
rhg: Initial repository locking
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
230 ) -> Result<R, LockError> { |
5734b03ecf3e
rhg: Initial repository locking
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
231 try_with_lock_no_wait(self.hg_vfs(), "wlock", f) |
5734b03ecf3e
rhg: Initial repository locking
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
232 } |
5734b03ecf3e
rhg: Initial repository locking
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
233 |
47374
bd88b6bfd8da
rhg: Add support for dirstate-v2
Simon Sapin <simon.sapin@octobus.net>
parents:
46822
diff
changeset
|
234 pub fn has_dirstate_v2(&self) -> bool { |
bd88b6bfd8da
rhg: Add support for dirstate-v2
Simon Sapin <simon.sapin@octobus.net>
parents:
46822
diff
changeset
|
235 self.requirements |
bd88b6bfd8da
rhg: Add support for dirstate-v2
Simon Sapin <simon.sapin@octobus.net>
parents:
46822
diff
changeset
|
236 .contains(requirements::DIRSTATE_V2_REQUIREMENT) |
bd88b6bfd8da
rhg: Add support for dirstate-v2
Simon Sapin <simon.sapin@octobus.net>
parents:
46822
diff
changeset
|
237 } |
bd88b6bfd8da
rhg: Add support for dirstate-v2
Simon Sapin <simon.sapin@octobus.net>
parents:
46822
diff
changeset
|
238 |
48409
005ae1a343f8
rhg: add support for narrow clones and sparse checkouts
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48069
diff
changeset
|
239 pub fn has_sparse(&self) -> bool { |
005ae1a343f8
rhg: add support for narrow clones and sparse checkouts
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48069
diff
changeset
|
240 self.requirements.contains(requirements::SPARSE_REQUIREMENT) |
005ae1a343f8
rhg: add support for narrow clones and sparse checkouts
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48069
diff
changeset
|
241 } |
005ae1a343f8
rhg: add support for narrow clones and sparse checkouts
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48069
diff
changeset
|
242 |
005ae1a343f8
rhg: add support for narrow clones and sparse checkouts
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48069
diff
changeset
|
243 pub fn has_narrow(&self) -> bool { |
005ae1a343f8
rhg: add support for narrow clones and sparse checkouts
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48069
diff
changeset
|
244 self.requirements.contains(requirements::NARROW_REQUIREMENT) |
005ae1a343f8
rhg: add support for narrow clones and sparse checkouts
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48069
diff
changeset
|
245 } |
005ae1a343f8
rhg: add support for narrow clones and sparse checkouts
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48069
diff
changeset
|
246 |
49091
9b5334c1e499
rust-repo: extract a function for checking nodemap requirement
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
247 pub fn has_nodemap(&self) -> bool { |
9b5334c1e499
rust-repo: extract a function for checking nodemap requirement
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
248 self.requirements |
9b5334c1e499
rust-repo: extract a function for checking nodemap requirement
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
249 .contains(requirements::NODEMAP_REQUIREMENT) |
9b5334c1e499
rust-repo: extract a function for checking nodemap requirement
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
250 } |
9b5334c1e499
rust-repo: extract a function for checking nodemap requirement
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
251 |
47956
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
252 fn dirstate_file_contents(&self) -> Result<Vec<u8>, HgError> { |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
253 Ok(self |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
254 .hg_vfs() |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
255 .read("dirstate") |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
256 .io_not_found_as_none()? |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
257 .unwrap_or(Vec::new())) |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
258 } |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
259 |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
260 pub fn dirstate_parents(&self) -> Result<DirstateParents, HgError> { |
49177
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
261 Ok(*self |
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
262 .dirstate_parents |
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
263 .get_or_init(|| self.read_dirstate_parents())?) |
48419
c8659e61073d
rhg: Make Repo::dirstate_parents a LazyCell
Simon Sapin <simon.sapin@octobus.net>
parents:
48417
diff
changeset
|
264 } |
c8659e61073d
rhg: Make Repo::dirstate_parents a LazyCell
Simon Sapin <simon.sapin@octobus.net>
parents:
48417
diff
changeset
|
265 |
c8659e61073d
rhg: Make Repo::dirstate_parents a LazyCell
Simon Sapin <simon.sapin@octobus.net>
parents:
48417
diff
changeset
|
266 fn read_dirstate_parents(&self) -> Result<DirstateParents, HgError> { |
47956
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
267 let dirstate = self.dirstate_file_contents()?; |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
268 let parents = if dirstate.is_empty() { |
48420
c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
Simon Sapin <simon.sapin@octobus.net>
parents:
48419
diff
changeset
|
269 if self.has_dirstate_v2() { |
c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
Simon Sapin <simon.sapin@octobus.net>
parents:
48419
diff
changeset
|
270 self.dirstate_data_file_uuid.set(None); |
c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
Simon Sapin <simon.sapin@octobus.net>
parents:
48419
diff
changeset
|
271 } |
47956
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
272 DirstateParents::NULL |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
273 } else if self.has_dirstate_v2() { |
48420
c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
Simon Sapin <simon.sapin@octobus.net>
parents:
48419
diff
changeset
|
274 let docket = |
c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
Simon Sapin <simon.sapin@octobus.net>
parents:
48419
diff
changeset
|
275 crate::dirstate_tree::on_disk::read_docket(&dirstate)?; |
c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
Simon Sapin <simon.sapin@octobus.net>
parents:
48419
diff
changeset
|
276 self.dirstate_data_file_uuid |
c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
Simon Sapin <simon.sapin@octobus.net>
parents:
48419
diff
changeset
|
277 .set(Some(docket.uuid.to_owned())); |
c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
Simon Sapin <simon.sapin@octobus.net>
parents:
48419
diff
changeset
|
278 docket.parents() |
47374
bd88b6bfd8da
rhg: Add support for dirstate-v2
Simon Sapin <simon.sapin@octobus.net>
parents:
46822
diff
changeset
|
279 } else { |
bd88b6bfd8da
rhg: Add support for dirstate-v2
Simon Sapin <simon.sapin@octobus.net>
parents:
46822
diff
changeset
|
280 crate::dirstate::parsers::parse_dirstate_parents(&dirstate)? |
47674
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47407
diff
changeset
|
281 .clone() |
47374
bd88b6bfd8da
rhg: Add support for dirstate-v2
Simon Sapin <simon.sapin@octobus.net>
parents:
46822
diff
changeset
|
282 }; |
48419
c8659e61073d
rhg: Make Repo::dirstate_parents a LazyCell
Simon Sapin <simon.sapin@octobus.net>
parents:
48417
diff
changeset
|
283 self.dirstate_parents.set(parents); |
47674
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47407
diff
changeset
|
284 Ok(parents) |
46601
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46599
diff
changeset
|
285 } |
47956
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
286 |
48420
c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
Simon Sapin <simon.sapin@octobus.net>
parents:
48419
diff
changeset
|
287 fn read_dirstate_data_file_uuid( |
c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
Simon Sapin <simon.sapin@octobus.net>
parents:
48419
diff
changeset
|
288 &self, |
c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
Simon Sapin <simon.sapin@octobus.net>
parents:
48419
diff
changeset
|
289 ) -> Result<Option<Vec<u8>>, HgError> { |
c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
Simon Sapin <simon.sapin@octobus.net>
parents:
48419
diff
changeset
|
290 assert!( |
c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
Simon Sapin <simon.sapin@octobus.net>
parents:
48419
diff
changeset
|
291 self.has_dirstate_v2(), |
c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
Simon Sapin <simon.sapin@octobus.net>
parents:
48419
diff
changeset
|
292 "accessing dirstate data file ID without dirstate-v2" |
c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
Simon Sapin <simon.sapin@octobus.net>
parents:
48419
diff
changeset
|
293 ); |
c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
Simon Sapin <simon.sapin@octobus.net>
parents:
48419
diff
changeset
|
294 let dirstate = self.dirstate_file_contents()?; |
c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
Simon Sapin <simon.sapin@octobus.net>
parents:
48419
diff
changeset
|
295 if dirstate.is_empty() { |
c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
Simon Sapin <simon.sapin@octobus.net>
parents:
48419
diff
changeset
|
296 self.dirstate_parents.set(DirstateParents::NULL); |
c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
Simon Sapin <simon.sapin@octobus.net>
parents:
48419
diff
changeset
|
297 Ok(None) |
c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
Simon Sapin <simon.sapin@octobus.net>
parents:
48419
diff
changeset
|
298 } else { |
c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
Simon Sapin <simon.sapin@octobus.net>
parents:
48419
diff
changeset
|
299 let docket = |
c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
Simon Sapin <simon.sapin@octobus.net>
parents:
48419
diff
changeset
|
300 crate::dirstate_tree::on_disk::read_docket(&dirstate)?; |
c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
Simon Sapin <simon.sapin@octobus.net>
parents:
48419
diff
changeset
|
301 self.dirstate_parents.set(docket.parents()); |
c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
Simon Sapin <simon.sapin@octobus.net>
parents:
48419
diff
changeset
|
302 Ok(Some(docket.uuid.to_owned())) |
c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
Simon Sapin <simon.sapin@octobus.net>
parents:
48419
diff
changeset
|
303 } |
c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
Simon Sapin <simon.sapin@octobus.net>
parents:
48419
diff
changeset
|
304 } |
c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
Simon Sapin <simon.sapin@octobus.net>
parents:
48419
diff
changeset
|
305 |
47956
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
306 fn new_dirstate_map(&self) -> Result<OwningDirstateMap, DirstateError> { |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
307 let dirstate_file_contents = self.dirstate_file_contents()?; |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
308 if dirstate_file_contents.is_empty() { |
48419
c8659e61073d
rhg: Make Repo::dirstate_parents a LazyCell
Simon Sapin <simon.sapin@octobus.net>
parents:
48417
diff
changeset
|
309 self.dirstate_parents.set(DirstateParents::NULL); |
48420
c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
Simon Sapin <simon.sapin@octobus.net>
parents:
48419
diff
changeset
|
310 if self.has_dirstate_v2() { |
c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
Simon Sapin <simon.sapin@octobus.net>
parents:
48419
diff
changeset
|
311 self.dirstate_data_file_uuid.set(None); |
c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
Simon Sapin <simon.sapin@octobus.net>
parents:
48419
diff
changeset
|
312 } |
47956
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
313 Ok(OwningDirstateMap::new_empty(Vec::new())) |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
314 } else if self.has_dirstate_v2() { |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
315 let docket = crate::dirstate_tree::on_disk::read_docket( |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
316 &dirstate_file_contents, |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
317 )?; |
48419
c8659e61073d
rhg: Make Repo::dirstate_parents a LazyCell
Simon Sapin <simon.sapin@octobus.net>
parents:
48417
diff
changeset
|
318 self.dirstate_parents.set(docket.parents()); |
48420
c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
Simon Sapin <simon.sapin@octobus.net>
parents:
48419
diff
changeset
|
319 self.dirstate_data_file_uuid |
c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
Simon Sapin <simon.sapin@octobus.net>
parents:
48419
diff
changeset
|
320 .set(Some(docket.uuid.to_owned())); |
47956
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
321 let data_size = docket.data_size(); |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
322 let metadata = docket.tree_metadata(); |
50180
be019ac8c1e4
dirstate-v2: don't mmap the data file when on NFS
Raphaël Gomès <rgomes@octobus.net>
parents:
49217
diff
changeset
|
323 if crate::vfs::is_on_nfs_mount(docket.data_filename()) { |
be019ac8c1e4
dirstate-v2: don't mmap the data file when on NFS
Raphaël Gomès <rgomes@octobus.net>
parents:
49217
diff
changeset
|
324 // Don't mmap on NFS to prevent `SIGBUS` error on deletion |
be019ac8c1e4
dirstate-v2: don't mmap the data file when on NFS
Raphaël Gomès <rgomes@octobus.net>
parents:
49217
diff
changeset
|
325 OwningDirstateMap::new_v2( |
be019ac8c1e4
dirstate-v2: don't mmap the data file when on NFS
Raphaël Gomès <rgomes@octobus.net>
parents:
49217
diff
changeset
|
326 self.hg_vfs().read(docket.data_filename())?, |
be019ac8c1e4
dirstate-v2: don't mmap the data file when on NFS
Raphaël Gomès <rgomes@octobus.net>
parents:
49217
diff
changeset
|
327 data_size, |
be019ac8c1e4
dirstate-v2: don't mmap the data file when on NFS
Raphaël Gomès <rgomes@octobus.net>
parents:
49217
diff
changeset
|
328 metadata, |
be019ac8c1e4
dirstate-v2: don't mmap the data file when on NFS
Raphaël Gomès <rgomes@octobus.net>
parents:
49217
diff
changeset
|
329 ) |
be019ac8c1e4
dirstate-v2: don't mmap the data file when on NFS
Raphaël Gomès <rgomes@octobus.net>
parents:
49217
diff
changeset
|
330 } else if let Some(data_mmap) = self |
47956
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
331 .hg_vfs() |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
332 .mmap_open(docket.data_filename()) |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
333 .io_not_found_as_none()? |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
334 { |
49000
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48510
diff
changeset
|
335 OwningDirstateMap::new_v2(data_mmap, data_size, metadata) |
47956
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
336 } else { |
49000
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48510
diff
changeset
|
337 OwningDirstateMap::new_v2(Vec::new(), data_size, metadata) |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48510
diff
changeset
|
338 } |
47956
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
339 } else { |
49000
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48510
diff
changeset
|
340 let (map, parents) = |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48510
diff
changeset
|
341 OwningDirstateMap::new_v1(dirstate_file_contents)?; |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Raphaël Gomès <rgomes@octobus.net>
parents:
48510
diff
changeset
|
342 self.dirstate_parents.set(parents); |
47956
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
343 Ok(map) |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
344 } |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
345 } |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
346 |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
347 pub fn dirstate_map( |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
348 &self, |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
349 ) -> Result<Ref<OwningDirstateMap>, DirstateError> { |
49177
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
350 self.dirstate_map.get_or_init(|| self.new_dirstate_map()) |
47958
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
351 } |
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
352 |
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
353 pub fn dirstate_map_mut( |
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
354 &self, |
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
355 ) -> Result<RefMut<OwningDirstateMap>, DirstateError> { |
49177
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
356 self.dirstate_map |
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
357 .get_mut_or_init(|| self.new_dirstate_map()) |
47958
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
358 } |
47959
21d25e9ee58e
rust: Keep lazily-initialized Changelog and Manifest log on the Repo object
Simon Sapin <simon.sapin@octobus.net>
parents:
47958
diff
changeset
|
359 |
49090
a5ef50becea8
rust-revlog: make `Changelog` and `ManifestLog` unaware of `Repo`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49005
diff
changeset
|
360 fn new_changelog(&self) -> Result<Changelog, HgError> { |
49091
9b5334c1e499
rust-repo: extract a function for checking nodemap requirement
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
361 Changelog::open(&self.store_vfs(), self.has_nodemap()) |
47958
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
362 } |
47959
21d25e9ee58e
rust: Keep lazily-initialized Changelog and Manifest log on the Repo object
Simon Sapin <simon.sapin@octobus.net>
parents:
47958
diff
changeset
|
363 |
47963
001d747c2baf
rust: Return HgError instead of RevlogError in revlog constructors
Simon Sapin <simon.sapin@octobus.net>
parents:
47961
diff
changeset
|
364 pub fn changelog(&self) -> Result<Ref<Changelog>, HgError> { |
49177
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
365 self.changelog.get_or_init(|| self.new_changelog()) |
47959
21d25e9ee58e
rust: Keep lazily-initialized Changelog and Manifest log on the Repo object
Simon Sapin <simon.sapin@octobus.net>
parents:
47958
diff
changeset
|
366 } |
21d25e9ee58e
rust: Keep lazily-initialized Changelog and Manifest log on the Repo object
Simon Sapin <simon.sapin@octobus.net>
parents:
47958
diff
changeset
|
367 |
47963
001d747c2baf
rust: Return HgError instead of RevlogError in revlog constructors
Simon Sapin <simon.sapin@octobus.net>
parents:
47961
diff
changeset
|
368 pub fn changelog_mut(&self) -> Result<RefMut<Changelog>, HgError> { |
49177
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
369 self.changelog.get_mut_or_init(|| self.new_changelog()) |
47959
21d25e9ee58e
rust: Keep lazily-initialized Changelog and Manifest log on the Repo object
Simon Sapin <simon.sapin@octobus.net>
parents:
47958
diff
changeset
|
370 } |
21d25e9ee58e
rust: Keep lazily-initialized Changelog and Manifest log on the Repo object
Simon Sapin <simon.sapin@octobus.net>
parents:
47958
diff
changeset
|
371 |
49090
a5ef50becea8
rust-revlog: make `Changelog` and `ManifestLog` unaware of `Repo`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49005
diff
changeset
|
372 fn new_manifestlog(&self) -> Result<Manifestlog, HgError> { |
49091
9b5334c1e499
rust-repo: extract a function for checking nodemap requirement
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
373 Manifestlog::open(&self.store_vfs(), self.has_nodemap()) |
47959
21d25e9ee58e
rust: Keep lazily-initialized Changelog and Manifest log on the Repo object
Simon Sapin <simon.sapin@octobus.net>
parents:
47958
diff
changeset
|
374 } |
21d25e9ee58e
rust: Keep lazily-initialized Changelog and Manifest log on the Repo object
Simon Sapin <simon.sapin@octobus.net>
parents:
47958
diff
changeset
|
375 |
47963
001d747c2baf
rust: Return HgError instead of RevlogError in revlog constructors
Simon Sapin <simon.sapin@octobus.net>
parents:
47961
diff
changeset
|
376 pub fn manifestlog(&self) -> Result<Ref<Manifestlog>, HgError> { |
49177
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
377 self.manifestlog.get_or_init(|| self.new_manifestlog()) |
47959
21d25e9ee58e
rust: Keep lazily-initialized Changelog and Manifest log on the Repo object
Simon Sapin <simon.sapin@octobus.net>
parents:
47958
diff
changeset
|
378 } |
21d25e9ee58e
rust: Keep lazily-initialized Changelog and Manifest log on the Repo object
Simon Sapin <simon.sapin@octobus.net>
parents:
47958
diff
changeset
|
379 |
47963
001d747c2baf
rust: Return HgError instead of RevlogError in revlog constructors
Simon Sapin <simon.sapin@octobus.net>
parents:
47961
diff
changeset
|
380 pub fn manifestlog_mut(&self) -> Result<RefMut<Manifestlog>, HgError> { |
49177
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
381 self.manifestlog.get_mut_or_init(|| self.new_manifestlog()) |
47959
21d25e9ee58e
rust: Keep lazily-initialized Changelog and Manifest log on the Repo object
Simon Sapin <simon.sapin@octobus.net>
parents:
47958
diff
changeset
|
382 } |
47960
cfb6e6699b25
rust: Add Repo::manifest(revision)
Simon Sapin <simon.sapin@octobus.net>
parents:
47959
diff
changeset
|
383 |
47969
87e3f878e65f
rust: Rename get_node methods to data_for_node, get_rev to data_for_rev
Simon Sapin <simon.sapin@octobus.net>
parents:
47964
diff
changeset
|
384 /// Returns the manifest of the *changeset* with the given node ID |
47964
796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents:
47963
diff
changeset
|
385 pub fn manifest_for_node( |
796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents:
47963
diff
changeset
|
386 &self, |
796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents:
47963
diff
changeset
|
387 node: impl Into<NodePrefix>, |
796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents:
47963
diff
changeset
|
388 ) -> Result<Manifest, RevlogError> { |
47969
87e3f878e65f
rust: Rename get_node methods to data_for_node, get_rev to data_for_rev
Simon Sapin <simon.sapin@octobus.net>
parents:
47964
diff
changeset
|
389 self.manifestlog()?.data_for_node( |
47964
796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents:
47963
diff
changeset
|
390 self.changelog()? |
47969
87e3f878e65f
rust: Rename get_node methods to data_for_node, get_rev to data_for_rev
Simon Sapin <simon.sapin@octobus.net>
parents:
47964
diff
changeset
|
391 .data_for_node(node.into())? |
47964
796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents:
47963
diff
changeset
|
392 .manifest_node()? |
796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents:
47963
diff
changeset
|
393 .into(), |
796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents:
47963
diff
changeset
|
394 ) |
796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents:
47963
diff
changeset
|
395 } |
796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents:
47963
diff
changeset
|
396 |
47969
87e3f878e65f
rust: Rename get_node methods to data_for_node, get_rev to data_for_rev
Simon Sapin <simon.sapin@octobus.net>
parents:
47964
diff
changeset
|
397 /// Returns the manifest of the *changeset* with the given revision number |
47964
796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents:
47963
diff
changeset
|
398 pub fn manifest_for_rev( |
47960
cfb6e6699b25
rust: Add Repo::manifest(revision)
Simon Sapin <simon.sapin@octobus.net>
parents:
47959
diff
changeset
|
399 &self, |
cfb6e6699b25
rust: Add Repo::manifest(revision)
Simon Sapin <simon.sapin@octobus.net>
parents:
47959
diff
changeset
|
400 revision: Revision, |
cfb6e6699b25
rust: Add Repo::manifest(revision)
Simon Sapin <simon.sapin@octobus.net>
parents:
47959
diff
changeset
|
401 ) -> Result<Manifest, RevlogError> { |
47969
87e3f878e65f
rust: Rename get_node methods to data_for_node, get_rev to data_for_rev
Simon Sapin <simon.sapin@octobus.net>
parents:
47964
diff
changeset
|
402 self.manifestlog()?.data_for_node( |
87e3f878e65f
rust: Rename get_node methods to data_for_node, get_rev to data_for_rev
Simon Sapin <simon.sapin@octobus.net>
parents:
47964
diff
changeset
|
403 self.changelog()? |
87e3f878e65f
rust: Rename get_node methods to data_for_node, get_rev to data_for_rev
Simon Sapin <simon.sapin@octobus.net>
parents:
47964
diff
changeset
|
404 .data_for_rev(revision)? |
87e3f878e65f
rust: Rename get_node methods to data_for_node, get_rev to data_for_rev
Simon Sapin <simon.sapin@octobus.net>
parents:
47964
diff
changeset
|
405 .manifest_node()? |
87e3f878e65f
rust: Rename get_node methods to data_for_node, get_rev to data_for_rev
Simon Sapin <simon.sapin@octobus.net>
parents:
47964
diff
changeset
|
406 .into(), |
47964
796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents:
47963
diff
changeset
|
407 ) |
47960
cfb6e6699b25
rust: Add Repo::manifest(revision)
Simon Sapin <simon.sapin@octobus.net>
parents:
47959
diff
changeset
|
408 } |
47961
4d2a5ca060e3
rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
47960
diff
changeset
|
409 |
48510
7f633432ca92
rhg: Sub-repositories are not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
48421
diff
changeset
|
410 pub fn has_subrepos(&self) -> Result<bool, DirstateError> { |
7f633432ca92
rhg: Sub-repositories are not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
48421
diff
changeset
|
411 if let Some(entry) = self.dirstate_map()?.get(HgPath::new(".hgsub"))? { |
49136
3f5e207f78be
rust: use `entry.tracked()` directly
Raphaël Gomès <rgomes@octobus.net>
parents:
49091
diff
changeset
|
412 Ok(entry.tracked()) |
48510
7f633432ca92
rhg: Sub-repositories are not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
48421
diff
changeset
|
413 } else { |
7f633432ca92
rhg: Sub-repositories are not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
48421
diff
changeset
|
414 Ok(false) |
7f633432ca92
rhg: Sub-repositories are not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
48421
diff
changeset
|
415 } |
7f633432ca92
rhg: Sub-repositories are not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
48421
diff
changeset
|
416 } |
7f633432ca92
rhg: Sub-repositories are not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
48421
diff
changeset
|
417 |
47963
001d747c2baf
rust: Return HgError instead of RevlogError in revlog constructors
Simon Sapin <simon.sapin@octobus.net>
parents:
47961
diff
changeset
|
418 pub fn filelog(&self, path: &HgPath) -> Result<Filelog, HgError> { |
47961
4d2a5ca060e3
rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
47960
diff
changeset
|
419 Filelog::open(self, path) |
4d2a5ca060e3
rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
47960
diff
changeset
|
420 } |
48421
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
421 |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
422 /// Write to disk any updates that were made through `dirstate_map_mut`. |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
423 /// |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
424 /// The "wlock" must be held while calling this. |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
425 /// See for example `try_with_wlock_no_wait`. |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
426 /// |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
427 /// TODO: have a `WritableRepo` type only accessible while holding the |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
428 /// lock? |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
429 pub fn write_dirstate(&self) -> Result<(), DirstateError> { |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
430 let map = self.dirstate_map()?; |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
431 // TODO: Maintain a `DirstateMap::dirty` flag, and return early here if |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
432 // it’s unset |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
433 let parents = self.dirstate_parents()?; |
49146
802e2c25dab8
rust-dirstate-v2: clean up previous data file after the docket is written
Raphaël Gomès <rgomes@octobus.net>
parents:
49145
diff
changeset
|
434 let (packed_dirstate, old_uuid_to_remove) = if self.has_dirstate_v2() { |
49177
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
435 let uuid_opt = self |
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
436 .dirstate_data_file_uuid |
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
437 .get_or_init(|| self.read_dirstate_data_file_uuid())?; |
49150
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Raphaël Gomès <rgomes@octobus.net>
parents:
49146
diff
changeset
|
438 let uuid_opt = uuid_opt.as_ref(); |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Raphaël Gomès <rgomes@octobus.net>
parents:
49146
diff
changeset
|
439 let can_append = uuid_opt.is_some(); |
49145
dd2503a63d33
rust-dirstate-v2: save proper data size if no new data on append
Raphaël Gomès <rgomes@octobus.net>
parents:
49000
diff
changeset
|
440 let (data, tree_metadata, append, old_data_size) = |
dd2503a63d33
rust-dirstate-v2: save proper data size if no new data on append
Raphaël Gomès <rgomes@octobus.net>
parents:
49000
diff
changeset
|
441 map.pack_v2(can_append)?; |
49150
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Raphaël Gomès <rgomes@octobus.net>
parents:
49146
diff
changeset
|
442 |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Raphaël Gomès <rgomes@octobus.net>
parents:
49146
diff
changeset
|
443 // Reuse the uuid, or generate a new one, keeping the old for |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Raphaël Gomès <rgomes@octobus.net>
parents:
49146
diff
changeset
|
444 // deletion. |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Raphaël Gomès <rgomes@octobus.net>
parents:
49146
diff
changeset
|
445 let (uuid, old_uuid) = match uuid_opt { |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Raphaël Gomès <rgomes@octobus.net>
parents:
49146
diff
changeset
|
446 Some(uuid) => { |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Raphaël Gomès <rgomes@octobus.net>
parents:
49146
diff
changeset
|
447 let as_str = std::str::from_utf8(uuid) |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Raphaël Gomès <rgomes@octobus.net>
parents:
49146
diff
changeset
|
448 .map_err(|_| { |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Raphaël Gomès <rgomes@octobus.net>
parents:
49146
diff
changeset
|
449 HgError::corrupted( |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Raphaël Gomès <rgomes@octobus.net>
parents:
49146
diff
changeset
|
450 "non-UTF-8 dirstate data file ID", |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Raphaël Gomès <rgomes@octobus.net>
parents:
49146
diff
changeset
|
451 ) |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Raphaël Gomès <rgomes@octobus.net>
parents:
49146
diff
changeset
|
452 })? |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Raphaël Gomès <rgomes@octobus.net>
parents:
49146
diff
changeset
|
453 .to_owned(); |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Raphaël Gomès <rgomes@octobus.net>
parents:
49146
diff
changeset
|
454 if append { |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Raphaël Gomès <rgomes@octobus.net>
parents:
49146
diff
changeset
|
455 (as_str, None) |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Raphaël Gomès <rgomes@octobus.net>
parents:
49146
diff
changeset
|
456 } else { |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Raphaël Gomès <rgomes@octobus.net>
parents:
49146
diff
changeset
|
457 (DirstateDocket::new_uid(), Some(as_str)) |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Raphaël Gomès <rgomes@octobus.net>
parents:
49146
diff
changeset
|
458 } |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Raphaël Gomès <rgomes@octobus.net>
parents:
49146
diff
changeset
|
459 } |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Raphaël Gomès <rgomes@octobus.net>
parents:
49146
diff
changeset
|
460 None => (DirstateDocket::new_uid(), None), |
48421
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
461 }; |
49150
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Raphaël Gomès <rgomes@octobus.net>
parents:
49146
diff
changeset
|
462 |
48421
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
463 let data_filename = format!("dirstate.{}", uuid); |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
464 let data_filename = self.hg_vfs().join(data_filename); |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
465 let mut options = std::fs::OpenOptions::new(); |
49202
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
466 options.write(true); |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
467 |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
468 // Why are we not using the O_APPEND flag when appending? |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
469 // |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
470 // - O_APPEND makes it trickier to deal with garbage at the end of |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
471 // the file, left by a previous uncommitted transaction. By |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
472 // starting the write at [old_data_size] we make sure we erase |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
473 // all such garbage. |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
474 // |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
475 // - O_APPEND requires to special-case 0-byte writes, whereas we |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
476 // don't need that. |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
477 // |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
478 // - Some OSes have bugs in implementation O_APPEND: |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
479 // revlog.py talks about a Solaris bug, but we also saw some ZFS |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
480 // bug: https://github.com/openzfs/zfs/pull/3124, |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
481 // https://github.com/openzfs/zfs/issues/13370 |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
482 // |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
483 if !append { |
50211
f5e4248e5bce
dirstate: add some debug output when writing the dirstate
Raphaël Gomès <rgomes@octobus.net>
parents:
50180
diff
changeset
|
484 log::trace!("creating a new dirstate data file"); |
49202
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
485 options.create_new(true); |
50211
f5e4248e5bce
dirstate: add some debug output when writing the dirstate
Raphaël Gomès <rgomes@octobus.net>
parents:
50180
diff
changeset
|
486 } else { |
f5e4248e5bce
dirstate: add some debug output when writing the dirstate
Raphaël Gomès <rgomes@octobus.net>
parents:
50180
diff
changeset
|
487 log::trace!("appending to the dirstate data file"); |
48421
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
488 } |
49202
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
489 |
48421
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
490 let data_size = (|| { |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
491 // TODO: loop and try another random ID if !append and this |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
492 // returns `ErrorKind::AlreadyExists`? Collision chance of two |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
493 // random IDs is one in 2**32 |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
494 let mut file = options.open(&data_filename)?; |
49202
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
495 if append { |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
496 file.seek(SeekFrom::Start(old_data_size as u64))?; |
49145
dd2503a63d33
rust-dirstate-v2: save proper data size if no new data on append
Raphaël Gomès <rgomes@octobus.net>
parents:
49000
diff
changeset
|
497 } |
49202
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
498 file.write_all(&data)?; |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
499 file.flush()?; |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
500 file.seek(SeekFrom::Current(0)) |
48421
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
501 })() |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
502 .when_writing_file(&data_filename)?; |
49146
802e2c25dab8
rust-dirstate-v2: clean up previous data file after the docket is written
Raphaël Gomès <rgomes@octobus.net>
parents:
49145
diff
changeset
|
503 |
802e2c25dab8
rust-dirstate-v2: clean up previous data file after the docket is written
Raphaël Gomès <rgomes@octobus.net>
parents:
49145
diff
changeset
|
504 let packed_dirstate = DirstateDocket::serialize( |
48421
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
505 parents, |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
506 tree_metadata, |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
507 data_size, |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
508 uuid.as_bytes(), |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
509 ) |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
510 .map_err(|_: std::num::TryFromIntError| { |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
511 HgError::corrupted("overflow in dirstate docket serialization") |
49146
802e2c25dab8
rust-dirstate-v2: clean up previous data file after the docket is written
Raphaël Gomès <rgomes@octobus.net>
parents:
49145
diff
changeset
|
512 })?; |
802e2c25dab8
rust-dirstate-v2: clean up previous data file after the docket is written
Raphaël Gomès <rgomes@octobus.net>
parents:
49145
diff
changeset
|
513 |
802e2c25dab8
rust-dirstate-v2: clean up previous data file after the docket is written
Raphaël Gomès <rgomes@octobus.net>
parents:
49145
diff
changeset
|
514 (packed_dirstate, old_uuid) |
48421
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
515 } else { |
49146
802e2c25dab8
rust-dirstate-v2: clean up previous data file after the docket is written
Raphaël Gomès <rgomes@octobus.net>
parents:
49145
diff
changeset
|
516 (map.pack_v1(parents)?, None) |
48421
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
517 }; |
49146
802e2c25dab8
rust-dirstate-v2: clean up previous data file after the docket is written
Raphaël Gomès <rgomes@octobus.net>
parents:
49145
diff
changeset
|
518 |
802e2c25dab8
rust-dirstate-v2: clean up previous data file after the docket is written
Raphaël Gomès <rgomes@octobus.net>
parents:
49145
diff
changeset
|
519 let vfs = self.hg_vfs(); |
802e2c25dab8
rust-dirstate-v2: clean up previous data file after the docket is written
Raphaël Gomès <rgomes@octobus.net>
parents:
49145
diff
changeset
|
520 vfs.atomic_write("dirstate", &packed_dirstate)?; |
802e2c25dab8
rust-dirstate-v2: clean up previous data file after the docket is written
Raphaël Gomès <rgomes@octobus.net>
parents:
49145
diff
changeset
|
521 if let Some(uuid) = old_uuid_to_remove { |
802e2c25dab8
rust-dirstate-v2: clean up previous data file after the docket is written
Raphaël Gomès <rgomes@octobus.net>
parents:
49145
diff
changeset
|
522 // Remove the old data file after the new docket pointing to the |
802e2c25dab8
rust-dirstate-v2: clean up previous data file after the docket is written
Raphaël Gomès <rgomes@octobus.net>
parents:
49145
diff
changeset
|
523 // new data file was written. |
802e2c25dab8
rust-dirstate-v2: clean up previous data file after the docket is written
Raphaël Gomès <rgomes@octobus.net>
parents:
49145
diff
changeset
|
524 vfs.remove_file(format!("dirstate.{}", uuid))?; |
802e2c25dab8
rust-dirstate-v2: clean up previous data file after the docket is written
Raphaël Gomès <rgomes@octobus.net>
parents:
49145
diff
changeset
|
525 } |
48421
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
526 Ok(()) |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
527 } |
47958
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
528 } |
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
529 |
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
530 /// Lazily-initialized component of `Repo` with interior mutability |
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
531 /// |
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
532 /// This differs from `OnceCell` in that the value can still be "deinitialized" |
49177
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
533 /// later by setting its inner `Option` to `None`. It also takes the |
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
534 /// initialization function as an argument when the value is requested, not |
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
535 /// when the instance is created. |
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
536 struct LazyCell<T> { |
47958
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
537 value: RefCell<Option<T>>, |
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
538 } |
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
539 |
49177
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
540 impl<T> LazyCell<T> { |
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
541 fn new() -> Self { |
47958
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
542 Self { |
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
543 value: RefCell::new(None), |
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
544 } |
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
545 } |
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
546 |
48419
c8659e61073d
rhg: Make Repo::dirstate_parents a LazyCell
Simon Sapin <simon.sapin@octobus.net>
parents:
48417
diff
changeset
|
547 fn set(&self, value: T) { |
c8659e61073d
rhg: Make Repo::dirstate_parents a LazyCell
Simon Sapin <simon.sapin@octobus.net>
parents:
48417
diff
changeset
|
548 *self.value.borrow_mut() = Some(value) |
c8659e61073d
rhg: Make Repo::dirstate_parents a LazyCell
Simon Sapin <simon.sapin@octobus.net>
parents:
48417
diff
changeset
|
549 } |
c8659e61073d
rhg: Make Repo::dirstate_parents a LazyCell
Simon Sapin <simon.sapin@octobus.net>
parents:
48417
diff
changeset
|
550 |
49177
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
551 fn get_or_init<E>( |
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
552 &self, |
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
553 init: impl Fn() -> Result<T, E>, |
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
554 ) -> Result<Ref<T>, E> { |
47958
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
555 let mut borrowed = self.value.borrow(); |
47956
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
556 if borrowed.is_none() { |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
557 drop(borrowed); |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
558 // Only use `borrow_mut` if it is really needed to avoid panic in |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
559 // case there is another outstanding borrow but mutation is not |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
560 // needed. |
49177
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
561 *self.value.borrow_mut() = Some(init()?); |
47958
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
562 borrowed = self.value.borrow() |
47956
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
563 } |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
564 Ok(Ref::map(borrowed, |option| option.as_ref().unwrap())) |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
565 } |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
566 |
49177
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
567 fn get_mut_or_init<E>( |
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
568 &self, |
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
569 init: impl Fn() -> Result<T, E>, |
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
570 ) -> Result<RefMut<T>, E> { |
47958
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
571 let mut borrowed = self.value.borrow_mut(); |
47956
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
572 if borrowed.is_none() { |
49177
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
573 *borrowed = Some(init()?); |
47956
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
574 } |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
575 Ok(RefMut::map(borrowed, |option| option.as_mut().unwrap())) |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
576 } |
46167
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
577 } |