annotate rust/hg-core/src/repo.rs @ 46753:97ac588b6d9e

rhg: Don’t make repository path absolute too early Some error messages want to include a relative path, which affects the output of some tests. Differential Revision: https://phab.mercurial-scm.org/D10138
author Simon Sapin <simon.sapin@octobus.net>
date Mon, 08 Mar 2021 08:35:43 +0100
parents 12d59eec7f1d
children 25e3dac511f0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
46545
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
1 use crate::config::{Config, ConfigError, ConfigParseError};
46638
1f55cd5b292f rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents: 46632
diff changeset
2 use crate::errors::{HgError, IoErrorContext, IoResultExt};
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
3 use crate::requirements;
46524
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
4 use crate::utils::files::get_path_from_bytes;
46753
97ac588b6d9e rhg: Don’t make repository path absolute too early
Simon Sapin <simon.sapin@octobus.net>
parents: 46748
diff changeset
5 use crate::utils::SliceExt;
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
6 use memmap::{Mmap, MmapOptions};
46524
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
7 use std::collections::HashSet;
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
8 use std::path::{Path, PathBuf};
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
9
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
10 /// A repository on disk
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
11 pub struct Repo {
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
12 working_directory: PathBuf,
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
13 dot_hg: PathBuf,
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
14 store: PathBuf,
46524
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
15 requirements: HashSet<String>,
46545
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
16 config: Config,
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
17 }
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
18
46514
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46511
diff changeset
19 #[derive(Debug, derive_more::From)]
46545
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
20 pub enum RepoError {
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
21 NotFound {
46555
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46545
diff changeset
22 at: PathBuf,
46514
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46511
diff changeset
23 },
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46511
diff changeset
24 #[from]
46545
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
25 ConfigParseError(ConfigParseError),
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
26 #[from]
46514
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46511
diff changeset
27 Other(HgError),
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46511
diff changeset
28 }
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46511
diff changeset
29
46545
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
30 impl From<ConfigError> for RepoError {
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
31 fn from(error: ConfigError) -> Self {
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
32 match error {
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
33 ConfigError::Parse(error) => error.into(),
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
34 ConfigError::Other(error) => error.into(),
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
35 }
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
36 }
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
37 }
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
38
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
39 /// Filesystem access abstraction for the contents of a given "base" diretory
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
40 #[derive(Clone, Copy)]
46638
1f55cd5b292f rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents: 46632
diff changeset
41 pub struct Vfs<'a> {
1f55cd5b292f rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents: 46632
diff changeset
42 pub(crate) base: &'a Path,
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
43 }
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 impl Repo {
46557
a25033eb43b5 rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents: 46555
diff changeset
46 /// 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: 46555
diff changeset
47 /// 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: 46555
diff changeset
48 /// ancestors.
46555
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46545
diff changeset
49 ///
46557
a25033eb43b5 rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents: 46555
diff changeset
50 /// 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: 46555
diff changeset
51 /// 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: 46555
diff changeset
52 /// 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: 46555
diff changeset
53 /// Having two methods would just move that `if` to almost all callers.
46555
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46545
diff changeset
54 pub fn find(
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46545
diff changeset
55 config: &Config,
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46545
diff changeset
56 explicit_path: Option<&Path>,
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46545
diff changeset
57 ) -> Result<Self, RepoError> {
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46545
diff changeset
58 if let Some(root) = explicit_path {
46753
97ac588b6d9e rhg: Don’t make repository path absolute too early
Simon Sapin <simon.sapin@octobus.net>
parents: 46748
diff changeset
59 if root.join(".hg").is_dir() {
97ac588b6d9e rhg: Don’t make repository path absolute too early
Simon Sapin <simon.sapin@octobus.net>
parents: 46748
diff changeset
60 Self::new_at_path(root.to_owned(), config)
97ac588b6d9e rhg: Don’t make repository path absolute too early
Simon Sapin <simon.sapin@octobus.net>
parents: 46748
diff changeset
61 } else if root.is_file() {
46743
dfd35823635b rhg: Fall back to Python for bundle repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46741
diff changeset
62 Err(HgError::unsupported("bundle repository").into())
46555
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46545
diff changeset
63 } else {
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46545
diff changeset
64 Err(RepoError::NotFound {
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46545
diff changeset
65 at: root.to_owned(),
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46545
diff changeset
66 })
46514
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46511
diff changeset
67 }
46555
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46545
diff changeset
68 } else {
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46545
diff changeset
69 let current_directory = crate::utils::current_dir()?;
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46545
diff changeset
70 // ancestors() is inclusive: it first yields `current_directory`
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46545
diff changeset
71 // as-is.
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46545
diff changeset
72 for ancestor in current_directory.ancestors() {
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46545
diff changeset
73 if ancestor.join(".hg").is_dir() {
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46545
diff changeset
74 return Self::new_at_path(ancestor.to_owned(), config);
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46545
diff changeset
75 }
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46545
diff changeset
76 }
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46545
diff changeset
77 Err(RepoError::NotFound {
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46545
diff changeset
78 at: current_directory,
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46545
diff changeset
79 })
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
80 }
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
81 }
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
82
46524
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
83 /// To be called after checking that `.hg` is a sub-directory
46544
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46543
diff changeset
84 fn new_at_path(
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46543
diff changeset
85 working_directory: PathBuf,
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46543
diff changeset
86 config: &Config,
46545
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
87 ) -> Result<Self, RepoError> {
46524
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
88 let dot_hg = working_directory.join(".hg");
46525
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46524
diff changeset
89
46545
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
90 let mut repo_config_files = Vec::new();
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
91 repo_config_files.push(dot_hg.join("hgrc"));
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
92 repo_config_files.push(dot_hg.join("hgrc-not-shared"));
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
93
46524
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
94 let hg_vfs = Vfs { base: &dot_hg };
46525
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46524
diff changeset
95 let mut reqs = requirements::load_if_exists(hg_vfs)?;
46524
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
96 let relative =
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
97 reqs.contains(requirements::RELATIVE_SHARED_REQUIREMENT);
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
98 let shared =
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
99 reqs.contains(requirements::SHARED_REQUIREMENT) || relative;
46525
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46524
diff changeset
100
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46524
diff changeset
101 // From `mercurial/localrepo.py`:
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46524
diff changeset
102 //
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46524
diff changeset
103 // if .hg/requires contains the sharesafe requirement, it means
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46524
diff changeset
104 // 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: 46524
diff changeset
105 // NOTE: presence of SHARESAFE_REQUIREMENT imply that store requirement
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46524
diff changeset
106 // 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: 46524
diff changeset
107 // is not present, refer checkrequirementscompat() for that
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46524
diff changeset
108 //
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46524
diff changeset
109 // 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: 46524
diff changeset
110 // 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: 46524
diff changeset
111 // .hg/requires for SHARESAFE_REQUIREMENT to detect whether the
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46524
diff changeset
112 // current repository needs to be reshared
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46524
diff changeset
113 let share_safe = reqs.contains(requirements::SHARESAFE_REQUIREMENT);
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46524
diff changeset
114
46524
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
115 let store_path;
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
116 if !shared {
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
117 store_path = dot_hg.join("store");
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
118 } else {
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
119 let bytes = hg_vfs.read("sharedpath")?;
46708
e8cd519a0a34 rhg: Ignore trailing newlines in .hg/sharedpath
Simon Sapin <simon.sapin@octobus.net>
parents: 46652
diff changeset
120 let mut shared_path =
e8cd519a0a34 rhg: Ignore trailing newlines in .hg/sharedpath
Simon Sapin <simon.sapin@octobus.net>
parents: 46652
diff changeset
121 get_path_from_bytes(bytes.trim_end_newlines()).to_owned();
46524
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
122 if relative {
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
123 shared_path = dot_hg.join(shared_path)
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
124 }
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
125 if !shared_path.is_dir() {
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
126 return Err(HgError::corrupted(format!(
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
127 ".hg/sharedpath points to nonexistent directory {}",
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
128 shared_path.display()
46545
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
129 ))
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
130 .into());
46524
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
131 }
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
132
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
133 store_path = shared_path.join("store");
46525
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46524
diff changeset
134
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46524
diff changeset
135 let source_is_share_safe =
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46524
diff changeset
136 requirements::load(Vfs { base: &shared_path })?
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46524
diff changeset
137 .contains(requirements::SHARESAFE_REQUIREMENT);
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46524
diff changeset
138
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46524
diff changeset
139 if share_safe && !source_is_share_safe {
46545
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
140 return Err(match config
46748
12d59eec7f1d rhg: Align with Python on some more error messages
Simon Sapin <simon.sapin@octobus.net>
parents: 46743
diff changeset
141 .get(b"share", b"safe-mismatch.source-not-safe")
46545
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
142 {
46544
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46543
diff changeset
143 Some(b"abort") | None => HgError::abort(
46748
12d59eec7f1d rhg: Align with Python on some more error messages
Simon Sapin <simon.sapin@octobus.net>
parents: 46743
diff changeset
144 "abort: share source does not support share-safe requirement\n\
12d59eec7f1d rhg: Align with Python on some more error messages
Simon Sapin <simon.sapin@octobus.net>
parents: 46743
diff changeset
145 (see `hg help config.format.use-share-safe` for more information)",
46544
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46543
diff changeset
146 ),
46545
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
147 _ => HgError::unsupported("share-safe downgrade"),
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
148 }
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
149 .into());
46525
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46524
diff changeset
150 } else if source_is_share_safe && !share_safe {
46544
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46543
diff changeset
151 return Err(
46748
12d59eec7f1d rhg: Align with Python on some more error messages
Simon Sapin <simon.sapin@octobus.net>
parents: 46743
diff changeset
152 match config.get(b"share", b"safe-mismatch.source-safe") {
46544
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46543
diff changeset
153 Some(b"abort") | None => HgError::abort(
46748
12d59eec7f1d rhg: Align with Python on some more error messages
Simon Sapin <simon.sapin@octobus.net>
parents: 46743
diff changeset
154 "abort: version mismatch: source uses share-safe \
12d59eec7f1d rhg: Align with Python on some more error messages
Simon Sapin <simon.sapin@octobus.net>
parents: 46743
diff changeset
155 functionality while the current share does not\n\
12d59eec7f1d rhg: Align with Python on some more error messages
Simon Sapin <simon.sapin@octobus.net>
parents: 46743
diff changeset
156 (see `hg help config.format.use-share-safe` for more information)",
46544
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46543
diff changeset
157 ),
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46543
diff changeset
158 _ => HgError::unsupported("share-safe upgrade"),
46545
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
159 }
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
160 .into(),
46544
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46543
diff changeset
161 );
46525
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46524
diff changeset
162 }
46545
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
163
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
164 if share_safe {
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
165 repo_config_files.insert(0, shared_path.join("hgrc"))
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
166 }
46524
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
167 }
46652
f64b6953db70 rhg: Bug fix: with share-safe, always read store requirements
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
168 if share_safe {
f64b6953db70 rhg: Bug fix: with share-safe, always read store requirements
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
169 reqs.extend(requirements::load(Vfs { base: &store_path })?);
f64b6953db70 rhg: Bug fix: with share-safe, always read store requirements
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
170 }
46524
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
171
46545
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
172 let repo_config = config.combine_with_repo(&repo_config_files)?;
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
173
46524
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
174 let repo = Self {
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
175 requirements: reqs,
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
176 working_directory,
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
177 store: store_path,
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
178 dot_hg,
46545
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
179 config: repo_config,
46524
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
180 };
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
181
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
182 requirements::check(&repo)?;
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
183
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
184 Ok(repo)
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
185 }
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
186
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
187 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
188 &self.working_directory
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
189 }
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
190
46524
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
191 pub fn requirements(&self) -> &HashSet<String> {
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
192 &self.requirements
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
193 }
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
194
46545
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
195 pub fn config(&self) -> &Config {
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
196 &self.config
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
197 }
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
198
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
199 /// 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
200 /// (`.hg/store`).
46638
1f55cd5b292f rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents: 46632
diff changeset
201 pub fn hg_vfs(&self) -> Vfs<'_> {
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
202 Vfs { base: &self.dot_hg }
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
203 }
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
204
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
205 /// For accessing repository store files (in `.hg/store`)
46638
1f55cd5b292f rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents: 46632
diff changeset
206 pub fn store_vfs(&self) -> Vfs<'_> {
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
207 Vfs { base: &self.store }
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
208 }
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
209
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
210 /// For accessing the working copy
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
211
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
212 // The undescore prefix silences the "never used" warning. Remove before
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
213 // using.
46638
1f55cd5b292f rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents: 46632
diff changeset
214 pub fn _working_directory_vfs(&self) -> Vfs<'_> {
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
215 Vfs {
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
216 base: &self.working_directory,
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
217 }
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
218 }
46640
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46638
diff changeset
219
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46638
diff changeset
220 pub fn dirstate_parents(
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46638
diff changeset
221 &self,
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46638
diff changeset
222 ) -> Result<crate::dirstate::DirstateParents, HgError> {
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46638
diff changeset
223 let dirstate = self.hg_vfs().mmap_open("dirstate")?;
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46638
diff changeset
224 let parents =
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46638
diff changeset
225 crate::dirstate::parsers::parse_dirstate_parents(&dirstate)?;
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46638
diff changeset
226 Ok(parents.clone())
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46638
diff changeset
227 }
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
228 }
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
229
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
230 impl Vfs<'_> {
46638
1f55cd5b292f rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents: 46632
diff changeset
231 pub fn join(&self, relative_path: impl AsRef<Path>) -> PathBuf {
46514
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46511
diff changeset
232 self.base.join(relative_path)
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46511
diff changeset
233 }
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46511
diff changeset
234
46638
1f55cd5b292f rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents: 46632
diff changeset
235 pub fn read(
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
236 &self,
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
237 relative_path: impl AsRef<Path>,
46511
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46510
diff changeset
238 ) -> Result<Vec<u8>, HgError> {
46514
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46511
diff changeset
239 let path = self.join(relative_path);
46638
1f55cd5b292f rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents: 46632
diff changeset
240 std::fs::read(&path).when_reading_file(&path)
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
241 }
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
242
46638
1f55cd5b292f rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents: 46632
diff changeset
243 pub fn mmap_open(
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
244 &self,
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
245 relative_path: impl AsRef<Path>,
46511
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46510
diff changeset
246 ) -> Result<Mmap, HgError> {
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46510
diff changeset
247 let path = self.base.join(relative_path);
46638
1f55cd5b292f rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents: 46632
diff changeset
248 let file = std::fs::File::open(&path).when_reading_file(&path)?;
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
249 // TODO: what are the safety requirements here?
46638
1f55cd5b292f rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents: 46632
diff changeset
250 let mmap = unsafe { MmapOptions::new().map(&file) }
1f55cd5b292f rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents: 46632
diff changeset
251 .when_reading_file(&path)?;
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
252 Ok(mmap)
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
253 }
46638
1f55cd5b292f rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents: 46632
diff changeset
254
1f55cd5b292f rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents: 46632
diff changeset
255 pub fn rename(
1f55cd5b292f rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents: 46632
diff changeset
256 &self,
1f55cd5b292f rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents: 46632
diff changeset
257 relative_from: impl AsRef<Path>,
1f55cd5b292f rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents: 46632
diff changeset
258 relative_to: impl AsRef<Path>,
1f55cd5b292f rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents: 46632
diff changeset
259 ) -> Result<(), HgError> {
1f55cd5b292f rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents: 46632
diff changeset
260 let from = self.join(relative_from);
1f55cd5b292f rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents: 46632
diff changeset
261 let to = self.join(relative_to);
1f55cd5b292f rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents: 46632
diff changeset
262 std::fs::rename(&from, &to)
1f55cd5b292f rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents: 46632
diff changeset
263 .with_context(|| IoErrorContext::RenamingFile { from, to })
1f55cd5b292f rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents: 46632
diff changeset
264 }
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
265 }