Mercurial > public > mercurial-scm > hg
annotate rust/hg-core/src/repo.rs @ 49558:363923bd51cd stable
dirstate-v2: hash the source of the ignore patterns as well
Fixes the test introduced in the last changeset. This caused the hash
to change, which means that the check in the test had to be adapted.
Since this hash is only done as a caching mechanism, invalidation does
not pose any backwards compatibility issues.
author | Rapha?l Gom?s <rgomes@octobus.net> |
---|---|
date | Wed, 02 Nov 2022 12:05:34 +0100 |
parents | 13dfad0f9f7a |
children | be019ac8c1e4 e98fd81bb151 |
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(); |
49000
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48510
diff
changeset
|
323 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
|
324 .hg_vfs() |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
325 .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
|
326 .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
|
327 { |
49000
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48510
diff
changeset
|
328 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
|
329 } else { |
49000
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48510
diff
changeset
|
330 OwningDirstateMap::new_v2(Vec::new(), data_size, metadata) |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48510
diff
changeset
|
331 } |
47956
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
332 } else { |
49000
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48510
diff
changeset
|
333 let (map, parents) = |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48510
diff
changeset
|
334 OwningDirstateMap::new_v1(dirstate_file_contents)?; |
dd6b67d5c256
rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48510
diff
changeset
|
335 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
|
336 Ok(map) |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
337 } |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
338 } |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
339 |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
340 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
|
341 &self, |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
342 ) -> 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
|
343 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
|
344 } |
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
345 |
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
346 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
|
347 &self, |
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
348 ) -> 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
|
349 self.dirstate_map |
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
350 .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
|
351 } |
47959
21d25e9ee58e
rust: Keep lazily-initialized Changelog and Manifest log on the Repo object
Simon Sapin <simon.sapin@octobus.net>
parents:
47958
diff
changeset
|
352 |
49090
a5ef50becea8
rust-revlog: make `Changelog` and `ManifestLog` unaware of `Repo`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49005
diff
changeset
|
353 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
|
354 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
|
355 } |
47959
21d25e9ee58e
rust: Keep lazily-initialized Changelog and Manifest log on the Repo object
Simon Sapin <simon.sapin@octobus.net>
parents:
47958
diff
changeset
|
356 |
47963
001d747c2baf
rust: Return HgError instead of RevlogError in revlog constructors
Simon Sapin <simon.sapin@octobus.net>
parents:
47961
diff
changeset
|
357 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
|
358 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
|
359 } |
21d25e9ee58e
rust: Keep lazily-initialized Changelog and Manifest log on the Repo object
Simon Sapin <simon.sapin@octobus.net>
parents:
47958
diff
changeset
|
360 |
47963
001d747c2baf
rust: Return HgError instead of RevlogError in revlog constructors
Simon Sapin <simon.sapin@octobus.net>
parents:
47961
diff
changeset
|
361 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
|
362 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
|
363 } |
21d25e9ee58e
rust: Keep lazily-initialized Changelog and Manifest log on the Repo object
Simon Sapin <simon.sapin@octobus.net>
parents:
47958
diff
changeset
|
364 |
49090
a5ef50becea8
rust-revlog: make `Changelog` and `ManifestLog` unaware of `Repo`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49005
diff
changeset
|
365 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
|
366 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
|
367 } |
21d25e9ee58e
rust: Keep lazily-initialized Changelog and Manifest log on the Repo object
Simon Sapin <simon.sapin@octobus.net>
parents:
47958
diff
changeset
|
368 |
47963
001d747c2baf
rust: Return HgError instead of RevlogError in revlog constructors
Simon Sapin <simon.sapin@octobus.net>
parents:
47961
diff
changeset
|
369 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
|
370 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
|
371 } |
21d25e9ee58e
rust: Keep lazily-initialized Changelog and Manifest log on the Repo object
Simon Sapin <simon.sapin@octobus.net>
parents:
47958
diff
changeset
|
372 |
47963
001d747c2baf
rust: Return HgError instead of RevlogError in revlog constructors
Simon Sapin <simon.sapin@octobus.net>
parents:
47961
diff
changeset
|
373 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
|
374 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
|
375 } |
47960
cfb6e6699b25
rust: Add Repo::manifest(revision)
Simon Sapin <simon.sapin@octobus.net>
parents:
47959
diff
changeset
|
376 |
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
|
377 /// 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
|
378 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
|
379 &self, |
796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents:
47963
diff
changeset
|
380 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
|
381 ) -> 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
|
382 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
|
383 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
|
384 .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
|
385 .manifest_node()? |
796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents:
47963
diff
changeset
|
386 .into(), |
796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents:
47963
diff
changeset
|
387 ) |
796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents:
47963
diff
changeset
|
388 } |
796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents:
47963
diff
changeset
|
389 |
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
|
390 /// 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
|
391 pub fn manifest_for_rev( |
47960
cfb6e6699b25
rust: Add Repo::manifest(revision)
Simon Sapin <simon.sapin@octobus.net>
parents:
47959
diff
changeset
|
392 &self, |
cfb6e6699b25
rust: Add Repo::manifest(revision)
Simon Sapin <simon.sapin@octobus.net>
parents:
47959
diff
changeset
|
393 revision: Revision, |
cfb6e6699b25
rust: Add Repo::manifest(revision)
Simon Sapin <simon.sapin@octobus.net>
parents:
47959
diff
changeset
|
394 ) -> 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
|
395 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
|
396 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
|
397 .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
|
398 .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
|
399 .into(), |
47964
796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents:
47963
diff
changeset
|
400 ) |
47960
cfb6e6699b25
rust: Add Repo::manifest(revision)
Simon Sapin <simon.sapin@octobus.net>
parents:
47959
diff
changeset
|
401 } |
47961
4d2a5ca060e3
rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
47960
diff
changeset
|
402 |
48510
7f633432ca92
rhg: Sub-repositories are not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
48421
diff
changeset
|
403 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
|
404 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
|
405 Ok(entry.tracked()) |
48510
7f633432ca92
rhg: Sub-repositories are not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
48421
diff
changeset
|
406 } else { |
7f633432ca92
rhg: Sub-repositories are not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
48421
diff
changeset
|
407 Ok(false) |
7f633432ca92
rhg: Sub-repositories are not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
48421
diff
changeset
|
408 } |
7f633432ca92
rhg: Sub-repositories are not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
48421
diff
changeset
|
409 } |
7f633432ca92
rhg: Sub-repositories are not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
48421
diff
changeset
|
410 |
47963
001d747c2baf
rust: Return HgError instead of RevlogError in revlog constructors
Simon Sapin <simon.sapin@octobus.net>
parents:
47961
diff
changeset
|
411 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
|
412 Filelog::open(self, path) |
4d2a5ca060e3
rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
47960
diff
changeset
|
413 } |
48421
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
414 |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
415 /// 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
|
416 /// |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
417 /// The "wlock" must be held while calling this. |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
418 /// See for example `try_with_wlock_no_wait`. |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
419 /// |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
420 /// 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
|
421 /// lock? |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
422 pub fn write_dirstate(&self) -> Result<(), DirstateError> { |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
423 let map = self.dirstate_map()?; |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
424 // 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
|
425 // it’s unset |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
426 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
|
427 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
|
428 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
|
429 .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
|
430 .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
|
431 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
|
432 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
|
433 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
|
434 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
|
435 |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49146
diff
changeset
|
436 // 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
|
437 // deletion. |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49146
diff
changeset
|
438 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
|
439 Some(uuid) => { |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49146
diff
changeset
|
440 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
|
441 .map_err(|_| { |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49146
diff
changeset
|
442 HgError::corrupted( |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49146
diff
changeset
|
443 "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
|
444 ) |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49146
diff
changeset
|
445 })? |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49146
diff
changeset
|
446 .to_owned(); |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49146
diff
changeset
|
447 if append { |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49146
diff
changeset
|
448 (as_str, None) |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49146
diff
changeset
|
449 } else { |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49146
diff
changeset
|
450 (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
|
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 None => (DirstateDocket::new_uid(), None), |
48421
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
454 }; |
49150
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49146
diff
changeset
|
455 |
48421
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
456 let data_filename = format!("dirstate.{}", uuid); |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
457 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
|
458 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
|
459 options.write(true); |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
460 |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
461 // 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
|
462 // |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
463 // - 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
|
464 // 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
|
465 // 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
|
466 // all such garbage. |
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 // - 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
|
469 // don't need that. |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
470 // |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
471 // - 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
|
472 // 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
|
473 // 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
|
474 // 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
|
475 // |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
476 if !append { |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
477 options.create_new(true); |
48421
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
478 } |
49202
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
479 |
48421
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
480 let data_size = (|| { |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
481 // 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
|
482 // returns `ErrorKind::AlreadyExists`? Collision chance of two |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
483 // random IDs is one in 2**32 |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
484 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
|
485 if append { |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
486 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
|
487 } |
49202
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
488 file.write_all(&data)?; |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
489 file.flush()?; |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
490 file.seek(SeekFrom::Current(0)) |
48421
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
491 })() |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
492 .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
|
493 |
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
|
494 let packed_dirstate = DirstateDocket::serialize( |
48421
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
495 parents, |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
496 tree_metadata, |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
497 data_size, |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
498 uuid.as_bytes(), |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
499 ) |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
500 .map_err(|_: std::num::TryFromIntError| { |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
501 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
|
502 })?; |
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 (packed_dirstate, old_uuid) |
48421
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
505 } 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
|
506 (map.pack_v1(parents)?, None) |
48421
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
507 }; |
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
|
508 |
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
|
509 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
|
510 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
|
511 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
|
512 // 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
|
513 // 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
|
514 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
|
515 } |
48421
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
516 Ok(()) |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
517 } |
47958
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
518 } |
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
519 |
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
520 /// 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
|
521 /// |
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
522 /// 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
|
523 /// 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
|
524 /// 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
|
525 /// 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
|
526 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
|
527 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
|
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 |
49177
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
530 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
|
531 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
|
532 Self { |
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
533 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
|
534 } |
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
535 } |
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
536 |
48419
c8659e61073d
rhg: Make Repo::dirstate_parents a LazyCell
Simon Sapin <simon.sapin@octobus.net>
parents:
48417
diff
changeset
|
537 fn set(&self, value: T) { |
c8659e61073d
rhg: Make Repo::dirstate_parents a LazyCell
Simon Sapin <simon.sapin@octobus.net>
parents:
48417
diff
changeset
|
538 *self.value.borrow_mut() = Some(value) |
c8659e61073d
rhg: Make Repo::dirstate_parents a LazyCell
Simon Sapin <simon.sapin@octobus.net>
parents:
48417
diff
changeset
|
539 } |
c8659e61073d
rhg: Make Repo::dirstate_parents a LazyCell
Simon Sapin <simon.sapin@octobus.net>
parents:
48417
diff
changeset
|
540 |
49177
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
541 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
|
542 &self, |
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
543 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
|
544 ) -> 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
|
545 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
|
546 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
|
547 drop(borrowed); |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
548 // 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
|
549 // 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
|
550 // needed. |
49177
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
551 *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
|
552 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
|
553 } |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
554 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
|
555 } |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
556 |
49177
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
557 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
|
558 &self, |
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
559 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
|
560 ) -> 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
|
561 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
|
562 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
|
563 *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
|
564 } |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
565 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
|
566 } |
46167
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
567 } |