Mercurial > public > mercurial-scm > hg
annotate rust/hg-core/src/repo.rs @ 53042:cdd7bf612c7b stable tip
bundle-spec: properly format boolean parameter (issue6960)
This was breaking automatic clone bundle generation. This changeset fixes it and
add a test to catch it in the future.
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Tue, 11 Mar 2025 02:29:42 +0100 |
parents | 94e2547e6f3d |
children |
rev | line source |
---|---|
46486
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
1 use crate::config::{Config, ConfigError, ConfigParseError}; |
52298
db065b33fa56
rust-dirstate: merge `dirstate_tree` module into `dirstate`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52290
diff
changeset
|
2 use crate::dirstate::dirstate_map::{DirstateIdentity, DirstateMapWriteMode}; |
db065b33fa56
rust-dirstate: merge `dirstate_tree` module into `dirstate`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52290
diff
changeset
|
3 use crate::dirstate::on_disk::Docket as DirstateDocket; |
db065b33fa56
rust-dirstate: merge `dirstate_tree` module into `dirstate`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52290
diff
changeset
|
4 use crate::dirstate::owning::OwningDirstateMap; |
52301
79e8118cd846
rust-lib: move `Dirstate*Error` to the `dirstate` module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52298
diff
changeset
|
5 use crate::dirstate::{DirstateError, DirstateParents}; |
47956
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}; |
52156
039b7caeb4d9
rust-revlog: introduce an `options` module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52050
diff
changeset
|
9 use crate::requirements::DIRSTATE_TRACKED_HINT_V1; |
52178
bd8081e9fd62
rust: don't star export from the `revlog` module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52167
diff
changeset
|
10 use crate::revlog::changelog::Changelog; |
47961
4d2a5ca060e3
rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
47960
diff
changeset
|
11 use crate::revlog::filelog::Filelog; |
52178
bd8081e9fd62
rust: don't star export from the `revlog` module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52167
diff
changeset
|
12 use crate::revlog::manifest::{Manifest, Manifestlog}; |
bd8081e9fd62
rust: don't star export from the `revlog` module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52167
diff
changeset
|
13 use crate::revlog::options::default_revlog_options; |
bd8081e9fd62
rust: don't star export from the `revlog` module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52167
diff
changeset
|
14 use crate::revlog::{RevlogError, RevlogType}; |
50228
fc8e37c380d3
dirstate: add a synchronisation point before doing a full dirstate read
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50227
diff
changeset
|
15 use crate::utils::debug::debug_wait_for_file_or_print; |
46462
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
16 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
|
17 use crate::utils::hg_path::HgPath; |
52760
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52301
diff
changeset
|
18 use crate::utils::strings::SliceExt; |
52167
7be39c5110c9
hg-core: add a complete VFS
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52156
diff
changeset
|
19 use crate::vfs::{is_dir, is_file, Vfs, VfsImpl}; |
52178
bd8081e9fd62
rust: don't star export from the `revlog` module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52167
diff
changeset
|
20 use crate::{exit_codes, requirements, NodePrefix, UncheckedRevision}; |
48419
c8659e61073d
rhg: Make Repo::dirstate_parents a LazyCell
Simon Sapin <simon.sapin@octobus.net>
parents:
48417
diff
changeset
|
21 use std::cell::{Ref, RefCell, RefMut}; |
46462
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
22 use std::collections::HashSet; |
48421
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
23 use std::io::Seek; |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
24 use std::io::SeekFrom; |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
25 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
|
26 use std::path::{Path, PathBuf}; |
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
27 |
50239
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
28 const V2_MAX_READ_ATTEMPTS: usize = 5; |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
29 |
52050
ea0467ed76aa
rust-dirstate-map: use a more precise identity
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52045
diff
changeset
|
30 /// Docket file identity, data file uuid and the data size |
ea0467ed76aa
rust-dirstate-map: use a more precise identity
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52045
diff
changeset
|
31 type DirstateV2Identity = (Option<DirstateIdentity>, Option<Vec<u8>>, usize); |
50252
a6b8b1ab9116
branching: merge stable into default
Pierre-Yves David <pierre-yves.david@octobus.net>
diff
changeset
|
32 |
46167
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
33 /// A repository on disk |
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
34 pub struct Repo { |
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
35 working_directory: PathBuf, |
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
36 dot_hg: PathBuf, |
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
37 store: PathBuf, |
46462
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
38 requirements: HashSet<String>, |
46486
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
39 config: Config, |
49177
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
40 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
|
41 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
|
42 changelog: LazyCell<Changelog>, |
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
43 manifestlog: LazyCell<Manifestlog>, |
46167
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
44 } |
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
45 |
46446
1dcd9c9975ed
rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents:
46443
diff
changeset
|
46 #[derive(Debug, derive_more::From)] |
46486
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
47 pub enum RepoError { |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
48 NotFound { |
46503
d8730ff51d5a
rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
49 at: PathBuf, |
46446
1dcd9c9975ed
rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents:
46443
diff
changeset
|
50 }, |
1dcd9c9975ed
rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents:
46443
diff
changeset
|
51 #[from] |
46486
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
52 ConfigParseError(ConfigParseError), |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
53 #[from] |
46446
1dcd9c9975ed
rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents:
46443
diff
changeset
|
54 Other(HgError), |
1dcd9c9975ed
rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents:
46443
diff
changeset
|
55 } |
1dcd9c9975ed
rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents:
46443
diff
changeset
|
56 |
46486
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
57 impl From<ConfigError> for RepoError { |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
58 fn from(error: ConfigError) -> Self { |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
59 match error { |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
60 ConfigError::Parse(error) => error.into(), |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
61 ConfigError::Other(error) => error.into(), |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
62 } |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
63 } |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
64 } |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
65 |
52042
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52032
diff
changeset
|
66 impl From<RepoError> for HgError { |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52032
diff
changeset
|
67 fn from(value: RepoError) -> Self { |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52032
diff
changeset
|
68 match value { |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52032
diff
changeset
|
69 RepoError::NotFound { at } => HgError::abort( |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52032
diff
changeset
|
70 format!( |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52032
diff
changeset
|
71 "abort: no repository found in '{}' (.hg not found)!", |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52032
diff
changeset
|
72 at.display() |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52032
diff
changeset
|
73 ), |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52032
diff
changeset
|
74 exit_codes::ABORT, |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52032
diff
changeset
|
75 None, |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52032
diff
changeset
|
76 ), |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52032
diff
changeset
|
77 RepoError::ConfigParseError(config_parse_error) => { |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52032
diff
changeset
|
78 HgError::Abort { |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52032
diff
changeset
|
79 message: String::from_utf8_lossy( |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52032
diff
changeset
|
80 &config_parse_error.message, |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52032
diff
changeset
|
81 ) |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52032
diff
changeset
|
82 .to_string(), |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52032
diff
changeset
|
83 detailed_exit_code: exit_codes::CONFIG_PARSE_ERROR_ABORT, |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52032
diff
changeset
|
84 hint: None, |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52032
diff
changeset
|
85 } |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52032
diff
changeset
|
86 } |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52032
diff
changeset
|
87 RepoError::Other(hg_error) => hg_error, |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52032
diff
changeset
|
88 } |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52032
diff
changeset
|
89 } |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52032
diff
changeset
|
90 } |
28a0eb21ff04
rust-cpython: add a util to get a `Repo` from a python path
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52032
diff
changeset
|
91 |
46167
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
92 impl Repo { |
47405
88119fffecc8
rhg: look for repository in ancestors also instead of cwd only
Pulkit Goyal <7895pulkit@gmail.com>
parents:
47404
diff
changeset
|
93 /// 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
|
94 /// its ancestors |
88119fffecc8
rhg: look for repository in ancestors also instead of cwd only
Pulkit Goyal <7895pulkit@gmail.com>
parents:
47404
diff
changeset
|
95 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
|
96 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
|
97 // 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
|
98 // as-is. |
88119fffecc8
rhg: look for repository in ancestors also instead of cwd only
Pulkit Goyal <7895pulkit@gmail.com>
parents:
47404
diff
changeset
|
99 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
|
100 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
|
101 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
|
102 } |
88119fffecc8
rhg: look for repository in ancestors also instead of cwd only
Pulkit Goyal <7895pulkit@gmail.com>
parents:
47404
diff
changeset
|
103 } |
49930
e98fd81bb151
rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49217
diff
changeset
|
104 Err(RepoError::NotFound { |
47405
88119fffecc8
rhg: look for repository in ancestors also instead of cwd only
Pulkit Goyal <7895pulkit@gmail.com>
parents:
47404
diff
changeset
|
105 at: current_directory, |
49930
e98fd81bb151
rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49217
diff
changeset
|
106 }) |
47405
88119fffecc8
rhg: look for repository in ancestors also instead of cwd only
Pulkit Goyal <7895pulkit@gmail.com>
parents:
47404
diff
changeset
|
107 } |
88119fffecc8
rhg: look for repository in ancestors also instead of cwd only
Pulkit Goyal <7895pulkit@gmail.com>
parents:
47404
diff
changeset
|
108 |
46505
a25033eb43b5
rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents:
46503
diff
changeset
|
109 /// 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
|
110 /// 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
|
111 /// ancestors. |
46503
d8730ff51d5a
rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
112 /// |
46505
a25033eb43b5
rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents:
46503
diff
changeset
|
113 /// 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
|
114 /// 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
|
115 /// 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
|
116 /// 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
|
117 pub fn find( |
d8730ff51d5a
rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
118 config: &Config, |
47404
ebdef6283798
rhg: read [paths] for `--repository` value
Pulkit Goyal <7895pulkit@gmail.com>
parents:
47374
diff
changeset
|
119 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
|
120 ) -> Result<Self, RepoError> { |
d8730ff51d5a
rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
121 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
|
122 if is_dir(root.join(".hg"))? { |
49930
e98fd81bb151
rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49217
diff
changeset
|
123 Self::new_at_path(root, config) |
47780
cf5f8da2244c
rhg: Propagate permission errors when finding a repository
Simon Sapin <simon.sapin@octobus.net>
parents:
47674
diff
changeset
|
124 } 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
|
125 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
|
126 } else { |
49930
e98fd81bb151
rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49217
diff
changeset
|
127 Err(RepoError::NotFound { at: root }) |
46446
1dcd9c9975ed
rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents:
46443
diff
changeset
|
128 } |
46503
d8730ff51d5a
rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
129 } else { |
47405
88119fffecc8
rhg: look for repository in ancestors also instead of cwd only
Pulkit Goyal <7895pulkit@gmail.com>
parents:
47404
diff
changeset
|
130 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
|
131 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
|
132 } |
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
133 } |
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
134 |
46462
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
135 /// 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
|
136 fn new_at_path( |
f031fe1c6ede
rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents:
46484
diff
changeset
|
137 working_directory: PathBuf, |
f031fe1c6ede
rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents:
46484
diff
changeset
|
138 config: &Config, |
46486
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
139 ) -> Result<Self, RepoError> { |
46462
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
140 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
|
141 |
49930
e98fd81bb151
rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49217
diff
changeset
|
142 let mut repo_config_files = |
e98fd81bb151
rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49217
diff
changeset
|
143 vec![dot_hg.join("hgrc"), dot_hg.join("hgrc-not-shared")]; |
46486
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
144 |
52167
7be39c5110c9
hg-core: add a complete VFS
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52156
diff
changeset
|
145 let hg_vfs = VfsImpl::new(dot_hg.to_owned(), false); |
51864 | 146 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
|
147 let relative = |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
148 reqs.contains(requirements::RELATIVE_SHARED_REQUIREMENT); |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
149 let shared = |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
150 reqs.contains(requirements::SHARED_REQUIREMENT) || relative; |
46463
95b276283b67
rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents:
46462
diff
changeset
|
151 |
95b276283b67
rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents:
46462
diff
changeset
|
152 // From `mercurial/localrepo.py`: |
95b276283b67
rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents:
46462
diff
changeset
|
153 // |
95b276283b67
rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents:
46462
diff
changeset
|
154 // 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
|
155 // 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
|
156 // 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
|
157 // 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
|
158 // is not present, refer checkrequirementscompat() for that |
95b276283b67
rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents:
46462
diff
changeset
|
159 // |
95b276283b67
rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents:
46462
diff
changeset
|
160 // 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
|
161 // 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
|
162 // .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
|
163 // current repository needs to be reshared |
95b276283b67
rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents:
46462
diff
changeset
|
164 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
|
165 |
46462
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
166 let store_path; |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
167 if !shared { |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
168 store_path = dot_hg.join("store"); |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
169 } else { |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
170 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
|
171 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
|
172 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
|
173 .to_owned(); |
46462
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
174 if relative { |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
175 shared_path = dot_hg.join(shared_path) |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
176 } |
47780
cf5f8da2244c
rhg: Propagate permission errors when finding a repository
Simon Sapin <simon.sapin@octobus.net>
parents:
47674
diff
changeset
|
177 if !is_dir(&shared_path)? { |
46462
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
178 return Err(HgError::corrupted(format!( |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
179 ".hg/sharedpath points to nonexistent directory {}", |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
180 shared_path.display() |
46486
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
181 )) |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
182 .into()); |
46462
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
183 } |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
184 |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
185 store_path = shared_path.join("store"); |
46463
95b276283b67
rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents:
46462
diff
changeset
|
186 |
52167
7be39c5110c9
hg-core: add a complete VFS
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52156
diff
changeset
|
187 let source_is_share_safe = requirements::load(VfsImpl::new( |
7be39c5110c9
hg-core: add a complete VFS
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52156
diff
changeset
|
188 shared_path.to_owned(), |
7be39c5110c9
hg-core: add a complete VFS
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52156
diff
changeset
|
189 true, |
7be39c5110c9
hg-core: add a complete VFS
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52156
diff
changeset
|
190 ))? |
51864 | 191 .contains(requirements::SHARESAFE_REQUIREMENT); |
46463
95b276283b67
rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents:
46462
diff
changeset
|
192 |
48809
1d5fd9def5ac
rhg: simplify the handling of share-safe config mismatch
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48510
diff
changeset
|
193 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
|
194 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
|
195 } |
46486
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
196 |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
197 if share_safe { |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
198 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
|
199 } |
46462
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
200 } |
46613
f64b6953db70
rhg: Bug fix: with share-safe, always read store requirements
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
201 if share_safe { |
52167
7be39c5110c9
hg-core: add a complete VFS
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52156
diff
changeset
|
202 reqs.extend(requirements::load(VfsImpl::new( |
7be39c5110c9
hg-core: add a complete VFS
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52156
diff
changeset
|
203 store_path.to_owned(), |
7be39c5110c9
hg-core: add a complete VFS
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52156
diff
changeset
|
204 true, |
7be39c5110c9
hg-core: add a complete VFS
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52156
diff
changeset
|
205 ))?); |
46613
f64b6953db70
rhg: Bug fix: with share-safe, always read store requirements
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
206 } |
46462
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
207 |
46741
25e3dac511f0
rhg: Add support for the HGRCSKIPREPO environment variable
Simon Sapin <simon.sapin@octobus.net>
parents:
46740
diff
changeset
|
208 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
|
209 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
|
210 } else { |
25e3dac511f0
rhg: Add support for the HGRCSKIPREPO environment variable
Simon Sapin <simon.sapin@octobus.net>
parents:
46740
diff
changeset
|
211 config.clone() |
25e3dac511f0
rhg: Add support for the HGRCSKIPREPO environment variable
Simon Sapin <simon.sapin@octobus.net>
parents:
46740
diff
changeset
|
212 }; |
46486
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
213 |
46462
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
214 let repo = Self { |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
215 requirements: reqs, |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
216 working_directory, |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
217 store: store_path, |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
218 dot_hg, |
46486
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
219 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
|
220 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
|
221 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
|
222 changelog: LazyCell::new(), |
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
223 manifestlog: LazyCell::new(), |
46462
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
224 }; |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
225 |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
226 requirements::check(&repo)?; |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
227 |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
228 Ok(repo) |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
229 } |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
230 |
46167
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
231 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
|
232 &self.working_directory |
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
233 } |
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
234 |
46462
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
235 pub fn requirements(&self) -> &HashSet<String> { |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
236 &self.requirements |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
237 } |
d03b0601e0eb
rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents:
46446
diff
changeset
|
238 |
46486
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
239 pub fn config(&self) -> &Config { |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
240 &self.config |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
241 } |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46485
diff
changeset
|
242 |
46167
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
243 /// 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
|
244 /// (`.hg/store`). |
51864 | 245 pub fn hg_vfs(&self) -> VfsImpl { |
52167
7be39c5110c9
hg-core: add a complete VFS
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52156
diff
changeset
|
246 VfsImpl::new(self.dot_hg.to_owned(), false) |
46167
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
247 } |
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
248 |
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
249 /// For accessing repository store files (in `.hg/store`) |
51864 | 250 pub fn store_vfs(&self) -> VfsImpl { |
52167
7be39c5110c9
hg-core: add a complete VFS
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52156
diff
changeset
|
251 VfsImpl::new(self.store.to_owned(), false) |
46167
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
252 } |
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
253 |
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
254 /// For accessing the working copy |
51864 | 255 pub fn working_directory_vfs(&self) -> VfsImpl { |
52167
7be39c5110c9
hg-core: add a complete VFS
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52156
diff
changeset
|
256 VfsImpl::new(self.working_directory.to_owned(), false) |
46167
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
257 } |
46601
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46599
diff
changeset
|
258 |
48417
5734b03ecf3e
rhg: Initial repository locking
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
259 pub fn try_with_wlock_no_wait<R>( |
5734b03ecf3e
rhg: Initial repository locking
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
260 &self, |
5734b03ecf3e
rhg: Initial repository locking
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
261 f: impl FnOnce() -> R, |
5734b03ecf3e
rhg: Initial repository locking
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
262 ) -> Result<R, LockError> { |
51864 | 263 try_with_lock_no_wait(&self.hg_vfs(), "wlock", f) |
48417
5734b03ecf3e
rhg: Initial repository locking
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
264 } |
5734b03ecf3e
rhg: Initial repository locking
Simon Sapin <simon.sapin@octobus.net>
parents:
48409
diff
changeset
|
265 |
50655
1e2c6cda2309
rust-dirstate: rename `has_dirstate_v2` to `use_dirstate_v2`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50252
diff
changeset
|
266 /// Whether this repo should use dirstate-v2. |
1e2c6cda2309
rust-dirstate: rename `has_dirstate_v2` to `use_dirstate_v2`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50252
diff
changeset
|
267 /// The presence of `dirstate-v2` in the requirements does not mean that |
1e2c6cda2309
rust-dirstate: rename `has_dirstate_v2` to `use_dirstate_v2`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50252
diff
changeset
|
268 /// the on-disk dirstate is necessarily in version 2. In most cases, |
1e2c6cda2309
rust-dirstate: rename `has_dirstate_v2` to `use_dirstate_v2`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50252
diff
changeset
|
269 /// a dirstate-v2 file will indeed be found, but in rare cases (like the |
1e2c6cda2309
rust-dirstate: rename `has_dirstate_v2` to `use_dirstate_v2`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50252
diff
changeset
|
270 /// upgrade mechanism being cut short), the on-disk version will be a |
1e2c6cda2309
rust-dirstate: rename `has_dirstate_v2` to `use_dirstate_v2`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50252
diff
changeset
|
271 /// v1 file. |
50657
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
272 /// Semantically, having a requirement only means that a client cannot |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
273 /// properly understand or properly update the repo if it lacks the support |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
274 /// for the required feature, but not that that feature is actually used |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
275 /// in all occasions. |
50655
1e2c6cda2309
rust-dirstate: rename `has_dirstate_v2` to `use_dirstate_v2`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50252
diff
changeset
|
276 pub fn use_dirstate_v2(&self) -> bool { |
47374
bd88b6bfd8da
rhg: Add support for dirstate-v2
Simon Sapin <simon.sapin@octobus.net>
parents:
46822
diff
changeset
|
277 self.requirements |
bd88b6bfd8da
rhg: Add support for dirstate-v2
Simon Sapin <simon.sapin@octobus.net>
parents:
46822
diff
changeset
|
278 .contains(requirements::DIRSTATE_V2_REQUIREMENT) |
bd88b6bfd8da
rhg: Add support for dirstate-v2
Simon Sapin <simon.sapin@octobus.net>
parents:
46822
diff
changeset
|
279 } |
bd88b6bfd8da
rhg: Add support for dirstate-v2
Simon Sapin <simon.sapin@octobus.net>
parents:
46822
diff
changeset
|
280 |
48409
005ae1a343f8
rhg: add support for narrow clones and sparse checkouts
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48069
diff
changeset
|
281 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
|
282 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
|
283 } |
005ae1a343f8
rhg: add support for narrow clones and sparse checkouts
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48069
diff
changeset
|
284 |
005ae1a343f8
rhg: add support for narrow clones and sparse checkouts
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48069
diff
changeset
|
285 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
|
286 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
|
287 } |
005ae1a343f8
rhg: add support for narrow clones and sparse checkouts
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
48069
diff
changeset
|
288 |
49091
9b5334c1e499
rust-repo: extract a function for checking nodemap requirement
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
289 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
|
290 self.requirements |
9b5334c1e499
rust-repo: extract a function for checking nodemap requirement
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
291 .contains(requirements::NODEMAP_REQUIREMENT) |
9b5334c1e499
rust-repo: extract a function for checking nodemap requirement
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
292 } |
9b5334c1e499
rust-repo: extract a function for checking nodemap requirement
Martin von Zweigbergk <martinvonz@google.com>
parents:
49090
diff
changeset
|
293 |
47956
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
294 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
|
295 Ok(self |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
296 .hg_vfs() |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
297 .read("dirstate") |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
298 .io_not_found_as_none()? |
49930
e98fd81bb151
rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49217
diff
changeset
|
299 .unwrap_or_default()) |
47956
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
300 } |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
301 |
52050
ea0467ed76aa
rust-dirstate-map: use a more precise identity
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52045
diff
changeset
|
302 fn dirstate_identity(&self) -> Result<Option<DirstateIdentity>, HgError> { |
50245
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50244
diff
changeset
|
303 Ok(self |
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50244
diff
changeset
|
304 .hg_vfs() |
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50244
diff
changeset
|
305 .symlink_metadata("dirstate") |
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50244
diff
changeset
|
306 .io_not_found_as_none()? |
52050
ea0467ed76aa
rust-dirstate-map: use a more precise identity
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52045
diff
changeset
|
307 .map(DirstateIdentity::from)) |
50245
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50244
diff
changeset
|
308 } |
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50244
diff
changeset
|
309 |
47956
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
310 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
|
311 Ok(*self |
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
312 .dirstate_parents |
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
313 .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
|
314 } |
c8659e61073d
rhg: Make Repo::dirstate_parents a LazyCell
Simon Sapin <simon.sapin@octobus.net>
parents:
48417
diff
changeset
|
315 |
c8659e61073d
rhg: Make Repo::dirstate_parents a LazyCell
Simon Sapin <simon.sapin@octobus.net>
parents:
48417
diff
changeset
|
316 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
|
317 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
|
318 let parents = if dirstate.is_empty() { |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
319 DirstateParents::NULL |
50655
1e2c6cda2309
rust-dirstate: rename `has_dirstate_v2` to `use_dirstate_v2`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50252
diff
changeset
|
320 } else if self.use_dirstate_v2() { |
52298
db065b33fa56
rust-dirstate: merge `dirstate_tree` module into `dirstate`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52290
diff
changeset
|
321 let docket_res = crate::dirstate::on_disk::read_docket(&dirstate); |
50657
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
322 match docket_res { |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
323 Ok(docket) => docket.parents(), |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
324 Err(_) => { |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
325 log::info!( |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
326 "Parsing dirstate docket failed, \ |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
327 falling back to dirstate-v1" |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
328 ); |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
329 *crate::dirstate::parsers::parse_dirstate_parents( |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
330 &dirstate, |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
331 )? |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
332 } |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
333 } |
47374
bd88b6bfd8da
rhg: Add support for dirstate-v2
Simon Sapin <simon.sapin@octobus.net>
parents:
46822
diff
changeset
|
334 } else { |
49930
e98fd81bb151
rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49217
diff
changeset
|
335 *crate::dirstate::parsers::parse_dirstate_parents(&dirstate)? |
47374
bd88b6bfd8da
rhg: Add support for dirstate-v2
Simon Sapin <simon.sapin@octobus.net>
parents:
46822
diff
changeset
|
336 }; |
48419
c8659e61073d
rhg: Make Repo::dirstate_parents a LazyCell
Simon Sapin <simon.sapin@octobus.net>
parents:
48417
diff
changeset
|
337 self.dirstate_parents.set(parents); |
47674
ff97e793ed36
dirstate-v2: Introduce a docket file
Simon Sapin <simon.sapin@octobus.net>
parents:
47407
diff
changeset
|
338 Ok(parents) |
46601
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46599
diff
changeset
|
339 } |
47956
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
340 |
50244
07d030b38097
rust-dirstate-v2: don't write dirstate if data file has changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50243
diff
changeset
|
341 /// Returns the information read from the dirstate docket necessary to |
07d030b38097
rust-dirstate-v2: don't write dirstate if data file has changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50243
diff
changeset
|
342 /// check if the data file has been updated/deleted by another process |
07d030b38097
rust-dirstate-v2: don't write dirstate if data file has changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50243
diff
changeset
|
343 /// since we last read the dirstate. |
52050
ea0467ed76aa
rust-dirstate-map: use a more precise identity
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52045
diff
changeset
|
344 /// Namely the docket file identity, data file uuid and the data size. |
50244
07d030b38097
rust-dirstate-v2: don't write dirstate if data file has changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50243
diff
changeset
|
345 fn get_dirstate_data_file_integrity( |
48420
c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
Simon Sapin <simon.sapin@octobus.net>
parents:
48419
diff
changeset
|
346 &self, |
52050
ea0467ed76aa
rust-dirstate-map: use a more precise identity
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52045
diff
changeset
|
347 ) -> Result<DirstateV2Identity, HgError> { |
48420
c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
Simon Sapin <simon.sapin@octobus.net>
parents:
48419
diff
changeset
|
348 assert!( |
50655
1e2c6cda2309
rust-dirstate: rename `has_dirstate_v2` to `use_dirstate_v2`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50252
diff
changeset
|
349 self.use_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
|
350 "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
|
351 ); |
50245
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50244
diff
changeset
|
352 // Get the identity before the contents since we could have a race |
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50244
diff
changeset
|
353 // between the two. Having an identity that is too old is fine, but |
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50244
diff
changeset
|
354 // one that is younger than the content change is bad. |
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50244
diff
changeset
|
355 let identity = self.dirstate_identity()?; |
48420
c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
Simon Sapin <simon.sapin@octobus.net>
parents:
48419
diff
changeset
|
356 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
|
357 if dirstate.is_empty() { |
50245
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50244
diff
changeset
|
358 Ok((identity, None, 0)) |
48420
c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
Simon Sapin <simon.sapin@octobus.net>
parents:
48419
diff
changeset
|
359 } else { |
52298
db065b33fa56
rust-dirstate: merge `dirstate_tree` module into `dirstate`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52290
diff
changeset
|
360 let docket_res = crate::dirstate::on_disk::read_docket(&dirstate); |
50657
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
361 match docket_res { |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
362 Ok(docket) => { |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
363 self.dirstate_parents.set(docket.parents()); |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
364 Ok(( |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
365 identity, |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
366 Some(docket.uuid.to_owned()), |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
367 docket.data_size(), |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
368 )) |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
369 } |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
370 Err(_) => { |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
371 log::info!( |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
372 "Parsing dirstate docket failed, \ |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
373 falling back to dirstate-v1" |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
374 ); |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
375 let parents = |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
376 *crate::dirstate::parsers::parse_dirstate_parents( |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
377 &dirstate, |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
378 )?; |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
379 self.dirstate_parents.set(parents); |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
380 Ok((identity, None, 0)) |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
381 } |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
382 } |
48420
c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
Simon Sapin <simon.sapin@octobus.net>
parents:
48419
diff
changeset
|
383 } |
c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
Simon Sapin <simon.sapin@octobus.net>
parents:
48419
diff
changeset
|
384 } |
c7c23bb036c9
rhg: Add lazy/cached dirstate data file ID parsing on Repo
Simon Sapin <simon.sapin@octobus.net>
parents:
48419
diff
changeset
|
385 |
47956
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
386 fn new_dirstate_map(&self) -> Result<OwningDirstateMap, DirstateError> { |
50655
1e2c6cda2309
rust-dirstate: rename `has_dirstate_v2` to `use_dirstate_v2`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50252
diff
changeset
|
387 if self.use_dirstate_v2() { |
50239
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
388 // The v2 dirstate is split into a docket and a data file. |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
389 // Since we don't always take the `wlock` to read it |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
390 // (like in `hg status`), it is susceptible to races. |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
391 // A simple retry method should be enough since full rewrites |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
392 // only happen when too much garbage data is present and |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
393 // this race is unlikely. |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
394 let mut tries = 0; |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
395 |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
396 while tries < V2_MAX_READ_ATTEMPTS { |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
397 tries += 1; |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
398 match self.read_docket_and_data_file() { |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
399 Ok(m) => { |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
400 return Ok(m); |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
401 } |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
402 Err(e) => match e { |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
403 DirstateError::Common(HgError::RaceDetected( |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
404 context, |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
405 )) => { |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
406 log::info!( |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
407 "dirstate read race detected {} (retry {}/{})", |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
408 context, |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
409 tries, |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
410 V2_MAX_READ_ATTEMPTS, |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
411 ); |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
412 continue; |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
413 } |
50657
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
414 _ => { |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
415 log::info!( |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
416 "Reading dirstate v2 failed, \ |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
417 falling back to v1" |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
418 ); |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
419 return self.new_dirstate_map_v1(); |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
420 } |
50239
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
421 }, |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
422 } |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
423 } |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
424 let error = HgError::abort( |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
425 format!("dirstate read race happened {tries} times in a row"), |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
426 255, |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
427 None, |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
428 ); |
50252
a6b8b1ab9116
branching: merge stable into default
Pierre-Yves David <pierre-yves.david@octobus.net>
diff
changeset
|
429 Err(DirstateError::Common(error)) |
50227
cbd4c9234e25
rust-repo: move dirstate-v2 opening to a separate method
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50222
diff
changeset
|
430 } else { |
50657
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
431 self.new_dirstate_map_v1() |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
432 } |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
433 } |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
434 |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
435 fn new_dirstate_map_v1(&self) -> Result<OwningDirstateMap, DirstateError> { |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
436 debug_wait_for_file_or_print(self.config(), "dirstate.pre-read-file"); |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
437 let identity = self.dirstate_identity()?; |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
438 let dirstate_file_contents = self.dirstate_file_contents()?; |
52043
e1fe336c007a
rust-repo: don't use on-disk dirstate parents in v1
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52042
diff
changeset
|
439 let parents = self.dirstate_parents()?; |
50657
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
440 if dirstate_file_contents.is_empty() { |
52043
e1fe336c007a
rust-repo: don't use on-disk dirstate parents in v1
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52042
diff
changeset
|
441 self.dirstate_parents.set(parents); |
52029
88aa21d654e5
rust-dirstate: actually remember the identity
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51864
diff
changeset
|
442 Ok(OwningDirstateMap::new_empty(Vec::new(), identity)) |
50657
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
443 } else { |
52043
e1fe336c007a
rust-repo: don't use on-disk dirstate parents in v1
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52042
diff
changeset
|
444 // Ignore the dirstate on-disk parents, they may have been set in |
e1fe336c007a
rust-repo: don't use on-disk dirstate parents in v1
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52042
diff
changeset
|
445 // the repo before |
e1fe336c007a
rust-repo: don't use on-disk dirstate parents in v1
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52042
diff
changeset
|
446 let (map, _) = |
50657
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
447 OwningDirstateMap::new_v1(dirstate_file_contents, identity)?; |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
448 self.dirstate_parents.set(parents); |
bf16ef96defe
rust-dirstate: fall back to v1 if reading v2 failed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50655
diff
changeset
|
449 Ok(map) |
50227
cbd4c9234e25
rust-repo: move dirstate-v2 opening to a separate method
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50222
diff
changeset
|
450 } |
cbd4c9234e25
rust-repo: move dirstate-v2 opening to a separate method
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50222
diff
changeset
|
451 } |
cbd4c9234e25
rust-repo: move dirstate-v2 opening to a separate method
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50222
diff
changeset
|
452 |
cbd4c9234e25
rust-repo: move dirstate-v2 opening to a separate method
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50222
diff
changeset
|
453 fn read_docket_and_data_file( |
cbd4c9234e25
rust-repo: move dirstate-v2 opening to a separate method
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50222
diff
changeset
|
454 &self, |
cbd4c9234e25
rust-repo: move dirstate-v2 opening to a separate method
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50222
diff
changeset
|
455 ) -> Result<OwningDirstateMap, DirstateError> { |
50228
fc8e37c380d3
dirstate: add a synchronisation point before doing a full dirstate read
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50227
diff
changeset
|
456 debug_wait_for_file_or_print(self.config(), "dirstate.pre-read-file"); |
47956
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
457 let dirstate_file_contents = self.dirstate_file_contents()?; |
50245
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50244
diff
changeset
|
458 let identity = self.dirstate_identity()?; |
47956
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
459 if dirstate_file_contents.is_empty() { |
52029
88aa21d654e5
rust-dirstate: actually remember the identity
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51864
diff
changeset
|
460 return Ok(OwningDirstateMap::new_empty(Vec::new(), identity)); |
50227
cbd4c9234e25
rust-repo: move dirstate-v2 opening to a separate method
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50222
diff
changeset
|
461 } |
52298
db065b33fa56
rust-dirstate: merge `dirstate_tree` module into `dirstate`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52290
diff
changeset
|
462 let docket = |
db065b33fa56
rust-dirstate: merge `dirstate_tree` module into `dirstate`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52290
diff
changeset
|
463 crate::dirstate::on_disk::read_docket(&dirstate_file_contents)?; |
50234
2be6d5782728
dirstate: add a synchronisation point in the middle of the read
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50228
diff
changeset
|
464 debug_wait_for_file_or_print( |
2be6d5782728
dirstate: add a synchronisation point in the middle of the read
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50228
diff
changeset
|
465 self.config(), |
2be6d5782728
dirstate: add a synchronisation point in the middle of the read
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50228
diff
changeset
|
466 "dirstate.post-docket-read-file", |
2be6d5782728
dirstate: add a synchronisation point in the middle of the read
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50228
diff
changeset
|
467 ); |
50227
cbd4c9234e25
rust-repo: move dirstate-v2 opening to a separate method
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50222
diff
changeset
|
468 self.dirstate_parents.set(docket.parents()); |
50243
6cce0afc1454
rust-dirstate: remember the data file uuid dirstate was loaded with
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50239
diff
changeset
|
469 let uuid = docket.uuid.to_owned(); |
50227
cbd4c9234e25
rust-repo: move dirstate-v2 opening to a separate method
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50222
diff
changeset
|
470 let data_size = docket.data_size(); |
50239
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
471 |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
472 let context = "between reading dirstate docket and data file"; |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
473 let race_error = HgError::RaceDetected(context.into()); |
50227
cbd4c9234e25
rust-repo: move dirstate-v2 opening to a separate method
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50222
diff
changeset
|
474 let metadata = docket.tree_metadata(); |
50239
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
475 |
50227
cbd4c9234e25
rust-repo: move dirstate-v2 opening to a separate method
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50222
diff
changeset
|
476 let mut map = if crate::vfs::is_on_nfs_mount(docket.data_filename()) { |
cbd4c9234e25
rust-repo: move dirstate-v2 opening to a separate method
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50222
diff
changeset
|
477 // Don't mmap on NFS to prevent `SIGBUS` error on deletion |
50239
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
478 let contents = self.hg_vfs().read(docket.data_filename()); |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
479 let contents = match contents { |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
480 Ok(c) => c, |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
481 Err(HgError::IoError { error, context }) => { |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
482 match error.raw_os_error().expect("real os error") { |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
483 // 2 = ENOENT, No such file or directory |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
484 // 116 = ESTALE, Stale NFS file handle |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
485 // |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
486 // TODO match on `error.kind()` when |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
487 // `ErrorKind::StaleNetworkFileHandle` is stable. |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
488 2 | 116 => { |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
489 // Race where the data file was deleted right after |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
490 // we read the docket, try again |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
491 return Err(race_error.into()); |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
492 } |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
493 _ => { |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
494 return Err( |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
495 HgError::IoError { error, context }.into() |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
496 ) |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
497 } |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
498 } |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
499 } |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
500 Err(e) => return Err(e.into()), |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
501 }; |
50245
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50244
diff
changeset
|
502 OwningDirstateMap::new_v2( |
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50244
diff
changeset
|
503 contents, data_size, metadata, uuid, identity, |
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50244
diff
changeset
|
504 ) |
50227
cbd4c9234e25
rust-repo: move dirstate-v2 opening to a separate method
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50222
diff
changeset
|
505 } else { |
50239
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
506 match self |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
507 .hg_vfs() |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
508 .mmap_open(docket.data_filename()) |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
509 .io_not_found_as_none() |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
510 { |
50243
6cce0afc1454
rust-dirstate: remember the data file uuid dirstate was loaded with
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50239
diff
changeset
|
511 Ok(Some(data_mmap)) => OwningDirstateMap::new_v2( |
50245
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50244
diff
changeset
|
512 data_mmap, data_size, metadata, uuid, identity, |
50243
6cce0afc1454
rust-dirstate: remember the data file uuid dirstate was loaded with
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50239
diff
changeset
|
513 ), |
50239
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
514 Ok(None) => { |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
515 // Race where the data file was deleted right after we |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
516 // read the docket, try again |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
517 return Err(race_error.into()); |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
518 } |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
519 Err(e) => return Err(e.into()), |
491f3dd080eb
dirstate: deal with read-race for pure rust code path (rhg)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50234
diff
changeset
|
520 } |
50227
cbd4c9234e25
rust-repo: move dirstate-v2 opening to a separate method
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50222
diff
changeset
|
521 }?; |
50222
ecd28d89c29e
dirstate-v2: add devel config option to control write behavior
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50221
diff
changeset
|
522 |
50227
cbd4c9234e25
rust-repo: move dirstate-v2 opening to a separate method
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50222
diff
changeset
|
523 let write_mode_config = self |
cbd4c9234e25
rust-repo: move dirstate-v2 opening to a separate method
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50222
diff
changeset
|
524 .config() |
cbd4c9234e25
rust-repo: move dirstate-v2 opening to a separate method
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50222
diff
changeset
|
525 .get_str(b"devel", b"dirstate.v2.data_update_mode") |
cbd4c9234e25
rust-repo: move dirstate-v2 opening to a separate method
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50222
diff
changeset
|
526 .unwrap_or(Some("auto")) |
cbd4c9234e25
rust-repo: move dirstate-v2 opening to a separate method
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50222
diff
changeset
|
527 .unwrap_or("auto"); // don't bother for devel options |
cbd4c9234e25
rust-repo: move dirstate-v2 opening to a separate method
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50222
diff
changeset
|
528 let write_mode = match write_mode_config { |
cbd4c9234e25
rust-repo: move dirstate-v2 opening to a separate method
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50222
diff
changeset
|
529 "auto" => DirstateMapWriteMode::Auto, |
cbd4c9234e25
rust-repo: move dirstate-v2 opening to a separate method
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50222
diff
changeset
|
530 "force-new" => DirstateMapWriteMode::ForceNewDataFile, |
cbd4c9234e25
rust-repo: move dirstate-v2 opening to a separate method
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50222
diff
changeset
|
531 "force-append" => DirstateMapWriteMode::ForceAppend, |
cbd4c9234e25
rust-repo: move dirstate-v2 opening to a separate method
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50222
diff
changeset
|
532 _ => DirstateMapWriteMode::Auto, |
cbd4c9234e25
rust-repo: move dirstate-v2 opening to a separate method
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50222
diff
changeset
|
533 }; |
50222
ecd28d89c29e
dirstate-v2: add devel config option to control write behavior
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50221
diff
changeset
|
534 |
52045
a8cf6a852f11
rust-dirstate: pass dirstate tracked key from the requirements
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52043
diff
changeset
|
535 let tracked_hint = |
a8cf6a852f11
rust-dirstate: pass dirstate tracked key from the requirements
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52043
diff
changeset
|
536 self.requirements().contains(DIRSTATE_TRACKED_HINT_V1); |
a8cf6a852f11
rust-dirstate: pass dirstate tracked key from the requirements
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52043
diff
changeset
|
537 |
a8cf6a852f11
rust-dirstate: pass dirstate tracked key from the requirements
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52043
diff
changeset
|
538 map.with_dmap_mut(|m| { |
a8cf6a852f11
rust-dirstate: pass dirstate tracked key from the requirements
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52043
diff
changeset
|
539 m.set_write_mode(write_mode); |
a8cf6a852f11
rust-dirstate: pass dirstate tracked key from the requirements
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52043
diff
changeset
|
540 m.set_tracked_hint(tracked_hint); |
a8cf6a852f11
rust-dirstate: pass dirstate tracked key from the requirements
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52043
diff
changeset
|
541 }); |
50222
ecd28d89c29e
dirstate-v2: add devel config option to control write behavior
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50221
diff
changeset
|
542 |
50227
cbd4c9234e25
rust-repo: move dirstate-v2 opening to a separate method
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50222
diff
changeset
|
543 Ok(map) |
47956
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
544 } |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
545 |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
546 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
|
547 &self, |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
548 ) -> 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
|
549 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
|
550 } |
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
551 |
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
552 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
|
553 &self, |
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
554 ) -> 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
|
555 self.dirstate_map |
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
556 .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
|
557 } |
47959
21d25e9ee58e
rust: Keep lazily-initialized Changelog and Manifest log on the Repo object
Simon Sapin <simon.sapin@octobus.net>
parents:
47958
diff
changeset
|
558 |
49090
a5ef50becea8
rust-revlog: make `Changelog` and `ManifestLog` unaware of `Repo`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49005
diff
changeset
|
559 fn new_changelog(&self) -> Result<Changelog, HgError> { |
51863
69b804c8e09e
rust: use new revlog configs in all revlog opening code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51188
diff
changeset
|
560 Changelog::open( |
69b804c8e09e
rust: use new revlog configs in all revlog opening code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51188
diff
changeset
|
561 &self.store_vfs(), |
52156
039b7caeb4d9
rust-revlog: introduce an `options` module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52050
diff
changeset
|
562 default_revlog_options( |
039b7caeb4d9
rust-revlog: introduce an `options` module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52050
diff
changeset
|
563 self.config(), |
039b7caeb4d9
rust-revlog: introduce an `options` module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52050
diff
changeset
|
564 self.requirements(), |
039b7caeb4d9
rust-revlog: introduce an `options` module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52050
diff
changeset
|
565 RevlogType::Changelog, |
039b7caeb4d9
rust-revlog: introduce an `options` module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52050
diff
changeset
|
566 )?, |
51863
69b804c8e09e
rust: use new revlog configs in all revlog opening code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51188
diff
changeset
|
567 ) |
47958
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
568 } |
47959
21d25e9ee58e
rust: Keep lazily-initialized Changelog and Manifest log on the Repo object
Simon Sapin <simon.sapin@octobus.net>
parents:
47958
diff
changeset
|
569 |
47963
001d747c2baf
rust: Return HgError instead of RevlogError in revlog constructors
Simon Sapin <simon.sapin@octobus.net>
parents:
47961
diff
changeset
|
570 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
|
571 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
|
572 } |
21d25e9ee58e
rust: Keep lazily-initialized Changelog and Manifest log on the Repo object
Simon Sapin <simon.sapin@octobus.net>
parents:
47958
diff
changeset
|
573 |
47963
001d747c2baf
rust: Return HgError instead of RevlogError in revlog constructors
Simon Sapin <simon.sapin@octobus.net>
parents:
47961
diff
changeset
|
574 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
|
575 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
|
576 } |
21d25e9ee58e
rust: Keep lazily-initialized Changelog and Manifest log on the Repo object
Simon Sapin <simon.sapin@octobus.net>
parents:
47958
diff
changeset
|
577 |
49090
a5ef50becea8
rust-revlog: make `Changelog` and `ManifestLog` unaware of `Repo`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49005
diff
changeset
|
578 fn new_manifestlog(&self) -> Result<Manifestlog, HgError> { |
51188
13f58ce70299
rust-revlog: teach the revlog opening code to read the repo options
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51117
diff
changeset
|
579 Manifestlog::open( |
13f58ce70299
rust-revlog: teach the revlog opening code to read the repo options
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51117
diff
changeset
|
580 &self.store_vfs(), |
52156
039b7caeb4d9
rust-revlog: introduce an `options` module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52050
diff
changeset
|
581 default_revlog_options( |
039b7caeb4d9
rust-revlog: introduce an `options` module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52050
diff
changeset
|
582 self.config(), |
039b7caeb4d9
rust-revlog: introduce an `options` module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52050
diff
changeset
|
583 self.requirements(), |
039b7caeb4d9
rust-revlog: introduce an `options` module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52050
diff
changeset
|
584 RevlogType::Manifestlog, |
039b7caeb4d9
rust-revlog: introduce an `options` module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52050
diff
changeset
|
585 )?, |
51188
13f58ce70299
rust-revlog: teach the revlog opening code to read the repo options
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51117
diff
changeset
|
586 ) |
47959
21d25e9ee58e
rust: Keep lazily-initialized Changelog and Manifest log on the Repo object
Simon Sapin <simon.sapin@octobus.net>
parents:
47958
diff
changeset
|
587 } |
21d25e9ee58e
rust: Keep lazily-initialized Changelog and Manifest log on the Repo object
Simon Sapin <simon.sapin@octobus.net>
parents:
47958
diff
changeset
|
588 |
47963
001d747c2baf
rust: Return HgError instead of RevlogError in revlog constructors
Simon Sapin <simon.sapin@octobus.net>
parents:
47961
diff
changeset
|
589 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
|
590 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
|
591 } |
21d25e9ee58e
rust: Keep lazily-initialized Changelog and Manifest log on the Repo object
Simon Sapin <simon.sapin@octobus.net>
parents:
47958
diff
changeset
|
592 |
47963
001d747c2baf
rust: Return HgError instead of RevlogError in revlog constructors
Simon Sapin <simon.sapin@octobus.net>
parents:
47961
diff
changeset
|
593 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
|
594 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
|
595 } |
47960
cfb6e6699b25
rust: Add Repo::manifest(revision)
Simon Sapin <simon.sapin@octobus.net>
parents:
47959
diff
changeset
|
596 |
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
|
597 /// 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
|
598 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
|
599 &self, |
796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents:
47963
diff
changeset
|
600 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
|
601 ) -> 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
|
602 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
|
603 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
|
604 .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
|
605 .manifest_node()? |
796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents:
47963
diff
changeset
|
606 .into(), |
796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents:
47963
diff
changeset
|
607 ) |
796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents:
47963
diff
changeset
|
608 } |
796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents:
47963
diff
changeset
|
609 |
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
|
610 /// 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
|
611 pub fn manifest_for_rev( |
47960
cfb6e6699b25
rust: Add Repo::manifest(revision)
Simon Sapin <simon.sapin@octobus.net>
parents:
47959
diff
changeset
|
612 &self, |
50974
1928b770e3e7
rust: use the new `UncheckedRevision` everywhere applicable
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50657
diff
changeset
|
613 revision: UncheckedRevision, |
47960
cfb6e6699b25
rust: Add Repo::manifest(revision)
Simon Sapin <simon.sapin@octobus.net>
parents:
47959
diff
changeset
|
614 ) -> 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
|
615 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
|
616 self.changelog()? |
52290
a3fa37bdb7ec
rust: normalize `_for_unchecked_rev` naming among revlogs and the index
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52178
diff
changeset
|
617 .data_for_unchecked_rev(revision)? |
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
|
618 .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
|
619 .into(), |
47964
796206e74b10
rhg: Reuse manifest when checking status of multiple ambiguous files
Simon Sapin <simon.sapin@octobus.net>
parents:
47963
diff
changeset
|
620 ) |
47960
cfb6e6699b25
rust: Add Repo::manifest(revision)
Simon Sapin <simon.sapin@octobus.net>
parents:
47959
diff
changeset
|
621 } |
47961
4d2a5ca060e3
rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
47960
diff
changeset
|
622 |
48510
7f633432ca92
rhg: Sub-repositories are not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
48421
diff
changeset
|
623 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
|
624 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
|
625 Ok(entry.tracked()) |
48510
7f633432ca92
rhg: Sub-repositories are not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
48421
diff
changeset
|
626 } else { |
7f633432ca92
rhg: Sub-repositories are not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
48421
diff
changeset
|
627 Ok(false) |
7f633432ca92
rhg: Sub-repositories are not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
48421
diff
changeset
|
628 } |
7f633432ca92
rhg: Sub-repositories are not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
48421
diff
changeset
|
629 } |
7f633432ca92
rhg: Sub-repositories are not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
48421
diff
changeset
|
630 |
47963
001d747c2baf
rust: Return HgError instead of RevlogError in revlog constructors
Simon Sapin <simon.sapin@octobus.net>
parents:
47961
diff
changeset
|
631 pub fn filelog(&self, path: &HgPath) -> Result<Filelog, HgError> { |
51863
69b804c8e09e
rust: use new revlog configs in all revlog opening code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51188
diff
changeset
|
632 Filelog::open( |
69b804c8e09e
rust: use new revlog configs in all revlog opening code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51188
diff
changeset
|
633 self, |
69b804c8e09e
rust: use new revlog configs in all revlog opening code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51188
diff
changeset
|
634 path, |
52156
039b7caeb4d9
rust-revlog: introduce an `options` module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52050
diff
changeset
|
635 default_revlog_options( |
039b7caeb4d9
rust-revlog: introduce an `options` module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52050
diff
changeset
|
636 self.config(), |
039b7caeb4d9
rust-revlog: introduce an `options` module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52050
diff
changeset
|
637 self.requirements(), |
039b7caeb4d9
rust-revlog: introduce an `options` module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52050
diff
changeset
|
638 RevlogType::Filelog, |
039b7caeb4d9
rust-revlog: introduce an `options` module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52050
diff
changeset
|
639 )?, |
51863
69b804c8e09e
rust: use new revlog configs in all revlog opening code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51188
diff
changeset
|
640 ) |
47961
4d2a5ca060e3
rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
47960
diff
changeset
|
641 } |
48421
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
642 /// 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
|
643 /// |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
644 /// The "wlock" must be held while calling this. |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
645 /// See for example `try_with_wlock_no_wait`. |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
646 /// |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
647 /// 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
|
648 /// lock? |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
649 pub fn write_dirstate(&self) -> Result<(), DirstateError> { |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
650 let map = self.dirstate_map()?; |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
651 // 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
|
652 // it’s unset |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
653 let parents = self.dirstate_parents()?; |
50655
1e2c6cda2309
rust-dirstate: rename `has_dirstate_v2` to `use_dirstate_v2`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50252
diff
changeset
|
654 let (packed_dirstate, old_uuid_to_remove) = if self.use_dirstate_v2() { |
50245
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50244
diff
changeset
|
655 let (identity, uuid, data_size) = |
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50244
diff
changeset
|
656 self.get_dirstate_data_file_integrity()?; |
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50244
diff
changeset
|
657 let identity_changed = identity != map.old_identity(); |
50244
07d030b38097
rust-dirstate-v2: don't write dirstate if data file has changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50243
diff
changeset
|
658 let uuid_changed = uuid.as_deref() != map.old_uuid(); |
07d030b38097
rust-dirstate-v2: don't write dirstate if data file has changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50243
diff
changeset
|
659 let data_length_changed = data_size != map.old_data_size(); |
07d030b38097
rust-dirstate-v2: don't write dirstate if data file has changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50243
diff
changeset
|
660 |
50245
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50244
diff
changeset
|
661 if identity_changed || uuid_changed || data_length_changed { |
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50244
diff
changeset
|
662 // If any of identity, uuid or length have changed since |
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50244
diff
changeset
|
663 // last disk read, don't write. |
50244
07d030b38097
rust-dirstate-v2: don't write dirstate if data file has changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50243
diff
changeset
|
664 // This is fine because either we're in a command that doesn't |
07d030b38097
rust-dirstate-v2: don't write dirstate if data file has changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50243
diff
changeset
|
665 // write anything too important (like `hg status`), or we're in |
07d030b38097
rust-dirstate-v2: don't write dirstate if data file has changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50243
diff
changeset
|
666 // `hg add` and we're supposed to have taken the lock before |
07d030b38097
rust-dirstate-v2: don't write dirstate if data file has changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50243
diff
changeset
|
667 // reading anyway. |
07d030b38097
rust-dirstate-v2: don't write dirstate if data file has changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50243
diff
changeset
|
668 // |
07d030b38097
rust-dirstate-v2: don't write dirstate if data file has changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50243
diff
changeset
|
669 // TODO complain loudly if we've changed anything important |
07d030b38097
rust-dirstate-v2: don't write dirstate if data file has changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50243
diff
changeset
|
670 // without taking the lock. |
07d030b38097
rust-dirstate-v2: don't write dirstate if data file has changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50243
diff
changeset
|
671 // (see `hg help config.format.use-dirstate-tracked-hint`) |
07d030b38097
rust-dirstate-v2: don't write dirstate if data file has changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50243
diff
changeset
|
672 log::debug!( |
07d030b38097
rust-dirstate-v2: don't write dirstate if data file has changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50243
diff
changeset
|
673 "dirstate has changed since last read, not updating." |
07d030b38097
rust-dirstate-v2: don't write dirstate if data file has changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50243
diff
changeset
|
674 ); |
07d030b38097
rust-dirstate-v2: don't write dirstate if data file has changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50243
diff
changeset
|
675 return Ok(()); |
07d030b38097
rust-dirstate-v2: don't write dirstate if data file has changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50243
diff
changeset
|
676 } |
07d030b38097
rust-dirstate-v2: don't write dirstate if data file has changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50243
diff
changeset
|
677 |
07d030b38097
rust-dirstate-v2: don't write dirstate if data file has changed
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50243
diff
changeset
|
678 let uuid_opt = map.old_uuid(); |
50221
1891086f6c7f
dirstate: use more than a bool to control append behavior
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50211
diff
changeset
|
679 let write_mode = if uuid_opt.is_some() { |
1891086f6c7f
dirstate: use more than a bool to control append behavior
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50211
diff
changeset
|
680 DirstateMapWriteMode::Auto |
1891086f6c7f
dirstate: use more than a bool to control append behavior
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50211
diff
changeset
|
681 } else { |
1891086f6c7f
dirstate: use more than a bool to control append behavior
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50211
diff
changeset
|
682 DirstateMapWriteMode::ForceNewDataFile |
1891086f6c7f
dirstate: use more than a bool to control append behavior
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50211
diff
changeset
|
683 }; |
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
|
684 let (data, tree_metadata, append, old_data_size) = |
50221
1891086f6c7f
dirstate: use more than a bool to control append behavior
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
50211
diff
changeset
|
685 map.pack_v2(write_mode)?; |
49150
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49146
diff
changeset
|
686 |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49146
diff
changeset
|
687 // 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
|
688 // deletion. |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49146
diff
changeset
|
689 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
|
690 Some(uuid) => { |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49146
diff
changeset
|
691 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
|
692 .map_err(|_| { |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49146
diff
changeset
|
693 HgError::corrupted( |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49146
diff
changeset
|
694 "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
|
695 ) |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49146
diff
changeset
|
696 })? |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49146
diff
changeset
|
697 .to_owned(); |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49146
diff
changeset
|
698 if append { |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49146
diff
changeset
|
699 (as_str, None) |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49146
diff
changeset
|
700 } else { |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49146
diff
changeset
|
701 (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
|
702 } |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49146
diff
changeset
|
703 } |
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49146
diff
changeset
|
704 None => (DirstateDocket::new_uid(), None), |
48421
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
705 }; |
49150
f2ef6a4f918f
rhg: fix dirstate-v2 data file removal system
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49146
diff
changeset
|
706 |
48421
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
707 let data_filename = format!("dirstate.{}", uuid); |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
708 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
|
709 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
|
710 options.write(true); |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
711 |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
712 // 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
|
713 // |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
714 // - 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
|
715 // 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
|
716 // 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
|
717 // all such garbage. |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
718 // |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
719 // - 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
|
720 // don't need that. |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
721 // |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
722 // - 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
|
723 // 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
|
724 // 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
|
725 // 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
|
726 // |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
727 if !append { |
50211
f5e4248e5bce
dirstate: add some debug output when writing the dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50180
diff
changeset
|
728 log::trace!("creating a new dirstate data file"); |
49202
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
729 options.create_new(true); |
50211
f5e4248e5bce
dirstate: add some debug output when writing the dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50180
diff
changeset
|
730 } else { |
f5e4248e5bce
dirstate: add some debug output when writing the dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50180
diff
changeset
|
731 log::trace!("appending to the dirstate data file"); |
48421
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
732 } |
49202
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
733 |
48421
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
734 let data_size = (|| { |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
735 // 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
|
736 // returns `ErrorKind::AlreadyExists`? Collision chance of two |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
737 // random IDs is one in 2**32 |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
738 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
|
739 if append { |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
740 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
|
741 } |
49202
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
742 file.write_all(&data)?; |
2d0e22171ef9
rhg: align the dirstate v2 writing algorithm with python
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49150
diff
changeset
|
743 file.flush()?; |
51117
532e74ad3ff6
rust: run a clippy pass with the latest stable version
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50974
diff
changeset
|
744 file.stream_position() |
48421
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
745 })() |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
746 .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
|
747 |
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
|
748 let packed_dirstate = DirstateDocket::serialize( |
48421
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
749 parents, |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
750 tree_metadata, |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
751 data_size, |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
752 uuid.as_bytes(), |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
753 ) |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
754 .map_err(|_: std::num::TryFromIntError| { |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
755 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
|
756 })?; |
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
|
757 |
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
|
758 (packed_dirstate, old_uuid) |
48421
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
759 } else { |
50245
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50244
diff
changeset
|
760 let identity = self.dirstate_identity()?; |
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50244
diff
changeset
|
761 if identity != map.old_identity() { |
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50244
diff
changeset
|
762 // If identity changed since last disk read, don't write. |
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50244
diff
changeset
|
763 // This is fine because either we're in a command that doesn't |
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50244
diff
changeset
|
764 // write anything too important (like `hg status`), or we're in |
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50244
diff
changeset
|
765 // `hg add` and we're supposed to have taken the lock before |
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50244
diff
changeset
|
766 // reading anyway. |
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50244
diff
changeset
|
767 // |
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50244
diff
changeset
|
768 // TODO complain loudly if we've changed anything important |
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50244
diff
changeset
|
769 // without taking the lock. |
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50244
diff
changeset
|
770 // (see `hg help config.format.use-dirstate-tracked-hint`) |
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50244
diff
changeset
|
771 log::debug!( |
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50244
diff
changeset
|
772 "dirstate has changed since last read, not updating." |
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50244
diff
changeset
|
773 ); |
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50244
diff
changeset
|
774 return Ok(()); |
dbe09fb038fc
rhg: remember the inode of .hg/dirstate
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50244
diff
changeset
|
775 } |
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
|
776 (map.pack_v1(parents)?, None) |
48421
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
777 }; |
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
|
778 |
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
|
779 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
|
780 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
|
781 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
|
782 // 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
|
783 // new data file was written. |
52167
7be39c5110c9
hg-core: add a complete VFS
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52156
diff
changeset
|
784 vfs.unlink(Path::new(&format!("dirstate.{}", uuid)))?; |
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
|
785 } |
48421
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
786 Ok(()) |
2097f63575a5
rhg: Add Repo::write_dirstate
Simon Sapin <simon.sapin@octobus.net>
parents:
48420
diff
changeset
|
787 } |
51188
13f58ce70299
rust-revlog: teach the revlog opening code to read the repo options
Rapha?l Gom?s <rgomes@octobus.net>
parents:
51117
diff
changeset
|
788 |
52031
babfa9ddca0e
rust-repo: add a method to get a `Node` from a `Revision` to the `Repo`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52029
diff
changeset
|
789 pub fn node(&self, rev: UncheckedRevision) -> Option<crate::Node> { |
babfa9ddca0e
rust-repo: add a method to get a `Node` from a `Revision` to the `Repo`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52029
diff
changeset
|
790 self.changelog() |
babfa9ddca0e
rust-repo: add a method to get a `Node` from a `Revision` to the `Repo`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52029
diff
changeset
|
791 .ok() |
52290
a3fa37bdb7ec
rust: normalize `_for_unchecked_rev` naming among revlogs and the index
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52178
diff
changeset
|
792 .and_then(|c| c.node_from_unchecked_rev(rev).copied()) |
52031
babfa9ddca0e
rust-repo: add a method to get a `Node` from a `Revision` to the `Repo`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52029
diff
changeset
|
793 } |
52032
d7bc6e482033
rust-repo: add a method to set the current parents
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52031
diff
changeset
|
794 |
d7bc6e482033
rust-repo: add a method to set the current parents
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52031
diff
changeset
|
795 /// Change the current working directory parents cached in the repo. |
d7bc6e482033
rust-repo: add a method to set the current parents
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52031
diff
changeset
|
796 /// |
d7bc6e482033
rust-repo: add a method to set the current parents
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52031
diff
changeset
|
797 /// TODO |
d7bc6e482033
rust-repo: add a method to set the current parents
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52031
diff
changeset
|
798 /// This does *not* do a lot of what it expected from a full `set_parents`: |
d7bc6e482033
rust-repo: add a method to set the current parents
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52031
diff
changeset
|
799 /// - parents should probably be stored in the dirstate |
d7bc6e482033
rust-repo: add a method to set the current parents
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52031
diff
changeset
|
800 /// - dirstate should have a "changing parents" context |
d7bc6e482033
rust-repo: add a method to set the current parents
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52031
diff
changeset
|
801 /// - dirstate should return copies if out of a merge context to be |
d7bc6e482033
rust-repo: add a method to set the current parents
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52031
diff
changeset
|
802 /// discarded within the repo context |
d7bc6e482033
rust-repo: add a method to set the current parents
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52031
diff
changeset
|
803 /// See `setparents` in `context.py`. |
d7bc6e482033
rust-repo: add a method to set the current parents
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52031
diff
changeset
|
804 pub fn manually_set_parents( |
d7bc6e482033
rust-repo: add a method to set the current parents
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52031
diff
changeset
|
805 &self, |
d7bc6e482033
rust-repo: add a method to set the current parents
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52031
diff
changeset
|
806 new_parents: DirstateParents, |
d7bc6e482033
rust-repo: add a method to set the current parents
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52031
diff
changeset
|
807 ) -> Result<(), HgError> { |
d7bc6e482033
rust-repo: add a method to set the current parents
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52031
diff
changeset
|
808 let mut parents = self.dirstate_parents.value.borrow_mut(); |
d7bc6e482033
rust-repo: add a method to set the current parents
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52031
diff
changeset
|
809 *parents = Some(new_parents); |
d7bc6e482033
rust-repo: add a method to set the current parents
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52031
diff
changeset
|
810 Ok(()) |
d7bc6e482033
rust-repo: add a method to set the current parents
Rapha?l Gom?s <rgomes@octobus.net>
parents:
52031
diff
changeset
|
811 } |
47958
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
812 } |
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
813 |
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
814 /// 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
|
815 /// |
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
816 /// 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
|
817 /// 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
|
818 /// 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
|
819 /// 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
|
820 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
|
821 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
|
822 } |
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
823 |
49177
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
824 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
|
825 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
|
826 Self { |
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
827 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
|
828 } |
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
829 } |
fc208d6faed3
rust: Move lazy initialization of `Repo::dirstate_map` into a generic struct
Simon Sapin <simon.sapin@octobus.net>
parents:
47956
diff
changeset
|
830 |
48419
c8659e61073d
rhg: Make Repo::dirstate_parents a LazyCell
Simon Sapin <simon.sapin@octobus.net>
parents:
48417
diff
changeset
|
831 fn set(&self, value: T) { |
c8659e61073d
rhg: Make Repo::dirstate_parents a LazyCell
Simon Sapin <simon.sapin@octobus.net>
parents:
48417
diff
changeset
|
832 *self.value.borrow_mut() = Some(value) |
c8659e61073d
rhg: Make Repo::dirstate_parents a LazyCell
Simon Sapin <simon.sapin@octobus.net>
parents:
48417
diff
changeset
|
833 } |
c8659e61073d
rhg: Make Repo::dirstate_parents a LazyCell
Simon Sapin <simon.sapin@octobus.net>
parents:
48417
diff
changeset
|
834 |
49177
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
835 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
|
836 &self, |
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
837 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
|
838 ) -> 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
|
839 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
|
840 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
|
841 drop(borrowed); |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
842 // 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
|
843 // 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
|
844 // needed. |
49177
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
845 *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
|
846 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
|
847 } |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
848 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
|
849 } |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
850 |
49177
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
851 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
|
852 &self, |
90a15199cbc6
rust-repo: make `Send` by not storing functions in `LazyCell`
Martin von Zweigbergk <martinvonz@google.com>
parents:
49164
diff
changeset
|
853 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
|
854 ) -> 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
|
855 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
|
856 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
|
857 *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
|
858 } |
81aedf1fc897
rust: Add Repo::dirstate_map and use it in `rhg status`
Simon Sapin <simon.sapin@octobus.net>
parents:
47952
diff
changeset
|
859 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
|
860 } |
46167
8a4914397d02
rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff
changeset
|
861 } |