annotate rust/hg-core/src/repo.rs @ 46617:a34cd9aa3323

copies-rust: yield both p1 and p2 copies in `ChangedFiles.actions()` Instead of filtering the relevant parent inside de ChangedFiles method, we now yield all copies information and let the caller do the filtering. Soon, the filtering will be replaced by dispatching. Differential Revision: https://phab.mercurial-scm.org/D9649
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Mon, 21 Dec 2020 10:24:16 +0100
parents a25033eb43b5
children 5ce2aa7c2ad5
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};
46511
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46510
diff changeset
2 use crate::errors::{HgError, 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;
46555
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46545
diff changeset
4 use crate::utils::current_dir;
46524
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
5 use crate::utils::files::get_path_from_bytes;
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)]
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
41 pub(crate) struct Vfs<'a> {
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
42 base: &'a Path,
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 {
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46545
diff changeset
59 // Having an absolute path isn’t necessary here but can help code
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46545
diff changeset
60 // elsewhere
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46545
diff changeset
61 let root = current_dir()?.join(root);
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46545
diff changeset
62 if root.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
63 Self::new_at_path(root, config)
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46545
diff changeset
64 } else {
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46545
diff changeset
65 Err(RepoError::NotFound {
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46545
diff changeset
66 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
67 })
46514
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46511
diff changeset
68 }
46555
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46545
diff changeset
69 } else {
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46545
diff changeset
70 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
71 // 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
72 // as-is.
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46545
diff changeset
73 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
74 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
75 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
76 }
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46545
diff changeset
77 }
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46545
diff changeset
78 Err(RepoError::NotFound {
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46545
diff changeset
79 at: current_directory,
d8730ff51d5a rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46545
diff changeset
80 })
46167
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 }
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
83
46557
a25033eb43b5 rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents: 46555
diff changeset
84 /// Like `Repo::find`, but not finding a repository is not an error if no
a25033eb43b5 rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents: 46555
diff changeset
85 /// explicit path is given. `Ok(None)` is returned in that case.
a25033eb43b5 rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents: 46555
diff changeset
86 ///
a25033eb43b5 rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents: 46555
diff changeset
87 /// If an explicit path *is* given, not finding a repository there is still
a25033eb43b5 rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents: 46555
diff changeset
88 /// an error.
a25033eb43b5 rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents: 46555
diff changeset
89 ///
a25033eb43b5 rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents: 46555
diff changeset
90 /// For sub-commands that don’t need a repository, configuration should
a25033eb43b5 rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents: 46555
diff changeset
91 /// still be affected by a repository’s `.hg/hgrc` file. This is the
a25033eb43b5 rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents: 46555
diff changeset
92 /// constructor to use.
a25033eb43b5 rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents: 46555
diff changeset
93 pub fn find_optional(
a25033eb43b5 rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents: 46555
diff changeset
94 config: &Config,
a25033eb43b5 rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents: 46555
diff changeset
95 explicit_path: Option<&Path>,
a25033eb43b5 rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents: 46555
diff changeset
96 ) -> Result<Option<Self>, RepoError> {
a25033eb43b5 rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents: 46555
diff changeset
97 match Self::find(config, explicit_path) {
a25033eb43b5 rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents: 46555
diff changeset
98 Ok(repo) => Ok(Some(repo)),
a25033eb43b5 rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents: 46555
diff changeset
99 Err(RepoError::NotFound { .. }) if explicit_path.is_none() => {
a25033eb43b5 rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents: 46555
diff changeset
100 Ok(None)
a25033eb43b5 rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents: 46555
diff changeset
101 }
a25033eb43b5 rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents: 46555
diff changeset
102 Err(error) => Err(error),
a25033eb43b5 rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents: 46555
diff changeset
103 }
a25033eb43b5 rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents: 46555
diff changeset
104 }
a25033eb43b5 rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents: 46555
diff changeset
105
46524
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
106 /// 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
107 fn new_at_path(
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46543
diff changeset
108 working_directory: PathBuf,
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46543
diff changeset
109 config: &Config,
46545
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
110 ) -> Result<Self, RepoError> {
46524
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
111 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
112
46545
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
113 let mut repo_config_files = Vec::new();
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
114 repo_config_files.push(dot_hg.join("hgrc"));
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
115 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
116
46524
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
117 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
118 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
119 let relative =
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
120 reqs.contains(requirements::RELATIVE_SHARED_REQUIREMENT);
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
121 let shared =
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
122 reqs.contains(requirements::SHARED_REQUIREMENT) || relative;
46525
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46524
diff changeset
123
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46524
diff changeset
124 // From `mercurial/localrepo.py`:
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46524
diff changeset
125 //
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46524
diff changeset
126 // 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
127 // 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
128 // 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
129 // 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
130 // is not present, refer checkrequirementscompat() for that
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46524
diff changeset
131 //
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46524
diff changeset
132 // 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
133 // 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
134 // .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
135 // current repository needs to be reshared
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46524
diff changeset
136 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
137
46524
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
138 let store_path;
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
139 if !shared {
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
140 store_path = dot_hg.join("store");
46525
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46524
diff changeset
141 if share_safe {
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46524
diff changeset
142 reqs.extend(requirements::load(Vfs { base: &store_path })?);
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46524
diff changeset
143 }
46524
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
144 } else {
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
145 let bytes = hg_vfs.read("sharedpath")?;
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
146 let mut shared_path = get_path_from_bytes(&bytes).to_owned();
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
147 if relative {
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
148 shared_path = dot_hg.join(shared_path)
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
149 }
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
150 if !shared_path.is_dir() {
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
151 return Err(HgError::corrupted(format!(
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
152 ".hg/sharedpath points to nonexistent directory {}",
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
153 shared_path.display()
46545
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
154 ))
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
155 .into());
46524
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
156 }
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
157
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
158 store_path = shared_path.join("store");
46525
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46524
diff changeset
159
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46524
diff changeset
160 let source_is_share_safe =
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46524
diff changeset
161 requirements::load(Vfs { base: &shared_path })?
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46524
diff changeset
162 .contains(requirements::SHARESAFE_REQUIREMENT);
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46524
diff changeset
163
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46524
diff changeset
164 if share_safe && !source_is_share_safe {
46545
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
165 return Err(match config
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
166 .get(b"safe-mismatch", b"source-not-safe")
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
167 {
46544
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46543
diff changeset
168 Some(b"abort") | None => HgError::abort(
46545
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
169 "share source does not support share-safe requirement",
46544
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46543
diff changeset
170 ),
46545
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
171 _ => HgError::unsupported("share-safe downgrade"),
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
172 }
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
173 .into());
46525
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46524
diff changeset
174 } 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
175 return Err(
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46543
diff changeset
176 match config.get(b"safe-mismatch", b"source-safe") {
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46543
diff changeset
177 Some(b"abort") | None => HgError::abort(
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46543
diff changeset
178 "version mismatch: source uses share-safe \
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46543
diff changeset
179 functionality while the current share does not",
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46543
diff changeset
180 ),
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46543
diff changeset
181 _ => HgError::unsupported("share-safe upgrade"),
46545
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
182 }
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
183 .into(),
46544
f031fe1c6ede rhg: Abort based on config on share-safe mismatch
Simon Sapin <simon.sapin@octobus.net>
parents: 46543
diff changeset
184 );
46525
95b276283b67 rhg: add support for share-safe
Simon Sapin <simon.sapin@octobus.net>
parents: 46524
diff changeset
185 }
46545
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
186
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
187 if share_safe {
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
188 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
189 }
46524
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
190 }
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
191
46545
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
192 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
193
46524
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
194 let repo = Self {
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
195 requirements: reqs,
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
196 working_directory,
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
197 store: store_path,
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
198 dot_hg,
46545
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
199 config: repo_config,
46524
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
200 };
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
201
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
202 requirements::check(&repo)?;
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
203
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
204 Ok(repo)
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
205 }
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
206
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
207 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
208 &self.working_directory
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
46524
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
211 pub fn requirements(&self) -> &HashSet<String> {
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
212 &self.requirements
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
213 }
d03b0601e0eb rhg: initial support for shared repositories
Simon Sapin <simon.sapin@octobus.net>
parents: 46514
diff changeset
214
46545
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
215 pub fn config(&self) -> &Config {
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
216 &self.config
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
217 }
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46544
diff changeset
218
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
219 /// 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
220 /// (`.hg/store`).
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
221 pub(crate) fn hg_vfs(&self) -> Vfs<'_> {
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
222 Vfs { base: &self.dot_hg }
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
223 }
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
224
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
225 /// For accessing repository store files (in `.hg/store`)
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
226 pub(crate) fn store_vfs(&self) -> Vfs<'_> {
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
227 Vfs { base: &self.store }
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 /// For accessing the working copy
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
231
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
232 // 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
233 // using.
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
234 pub(crate) fn _working_directory_vfs(&self) -> Vfs<'_> {
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
235 Vfs {
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
236 base: &self.working_directory,
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
237 }
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
238 }
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
239 }
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
240
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
241 impl Vfs<'_> {
46514
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46511
diff changeset
242 pub(crate) fn join(&self, relative_path: impl AsRef<Path>) -> PathBuf {
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46511
diff changeset
243 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
244 }
1dcd9c9975ed rust: Fold find_root and check_requirements into Repo::find
Simon Sapin <simon.sapin@octobus.net>
parents: 46511
diff changeset
245
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
246 pub(crate) fn read(
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
247 &self,
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
248 relative_path: impl AsRef<Path>,
46511
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46510
diff changeset
249 ) -> 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
250 let path = self.join(relative_path);
46511
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46510
diff changeset
251 std::fs::read(&path).for_file(&path)
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 pub(crate) fn mmap_open(
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
255 &self,
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
256 relative_path: impl AsRef<Path>,
46511
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46510
diff changeset
257 ) -> Result<Mmap, HgError> {
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46510
diff changeset
258 let path = self.base.join(relative_path);
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46510
diff changeset
259 let file = std::fs::File::open(&path).for_file(&path)?;
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
260 // TODO: what are the safety requirements here?
46511
43d63979a75e rust: use HgError in RevlogError and Vfs
Simon Sapin <simon.sapin@octobus.net>
parents: 46510
diff changeset
261 let mmap = unsafe { MmapOptions::new().map(&file) }.for_file(&path)?;
46167
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
262 Ok(mmap)
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
263 }
8a4914397d02 rust: introduce Repo and Vfs types for filesystem abstraction
Simon Sapin <simon.sapin@octobus.net>
parents:
diff changeset
264 }