Show More
@@ -11,7 +11,7 b' use super::layer;' | |||
|
11 | 11 | use crate::config::layer::{ConfigError, ConfigLayer, ConfigValue}; |
|
12 | 12 | use std::path::PathBuf; |
|
13 | 13 | |
|
14 | use crate::operations::find_root; | |
|
14 | use crate::repo::Repo; | |
|
15 | 15 | use crate::utils::files::read_whole_file; |
|
16 | 16 | |
|
17 | 17 | /// Holds the config values for the current repository |
@@ -76,10 +76,9 b' impl Config {' | |||
|
76 | 76 | |
|
77 | 77 | /// Loads the local config. In a future version, this will also load the |
|
78 | 78 | /// `$HOME/.hgrc` and more to mirror the Python implementation. |
|
79 | pub fn load() -> Result<Self, ConfigError> { | |
|
80 | let root = find_root().unwrap(); | |
|
79 | pub fn load_for_repo(repo: &Repo) -> Result<Self, ConfigError> { | |
|
81 | 80 | Ok(Self::load_from_explicit_sources(vec![ |
|
82 |
ConfigSource::AbsPath(r |
|
|
81 | ConfigSource::AbsPath(repo.hg_vfs().join("hgrc")), | |
|
83 | 82 | ])?) |
|
84 | 83 | } |
|
85 | 84 |
@@ -5,10 +5,8 b'' | |||
|
5 | 5 | mod cat; |
|
6 | 6 | mod debugdata; |
|
7 | 7 | mod dirstate_status; |
|
8 | mod find_root; | |
|
9 | 8 | mod list_tracked_files; |
|
10 | 9 | pub use cat::cat; |
|
11 | 10 | pub use debugdata::{debug_data, DebugDataKind}; |
|
12 | pub use find_root::{find_root, find_root_from_path, FindRootError}; | |
|
13 | 11 | pub use list_tracked_files::Dirstate; |
|
14 | 12 | pub use list_tracked_files::{list_rev_tracked_files, FilesForRev}; |
@@ -1,5 +1,4 b'' | |||
|
1 | 1 | use crate::errors::{HgError, IoResultExt}; |
|
2 | use crate::operations::{find_root, FindRootError}; | |
|
3 | 2 | use crate::requirements; |
|
4 | 3 | use memmap::{Mmap, MmapOptions}; |
|
5 | 4 | use std::path::{Path, PathBuf}; |
@@ -11,6 +10,15 b' pub struct Repo {' | |||
|
11 | 10 | store: PathBuf, |
|
12 | 11 | } |
|
13 | 12 | |
|
13 | #[derive(Debug, derive_more::From)] | |
|
14 | pub enum RepoFindError { | |
|
15 | NotFoundInCurrentDirectoryOrAncestors { | |
|
16 | current_directory: PathBuf, | |
|
17 | }, | |
|
18 | #[from] | |
|
19 | Other(HgError), | |
|
20 | } | |
|
21 | ||
|
14 | 22 | /// Filesystem access abstraction for the contents of a given "base" diretory |
|
15 | 23 | #[derive(Clone, Copy)] |
|
16 | 24 | pub(crate) struct Vfs<'a> { |
@@ -18,24 +26,26 b" pub(crate) struct Vfs<'a> {" | |||
|
18 | 26 | } |
|
19 | 27 | |
|
20 | 28 | impl Repo { |
|
21 | /// Returns `None` if the given path doesn’t look like a repository | |
|
22 |
/// |
|
|
23 | pub fn for_path(root: impl Into<PathBuf>) -> Self { | |
|
24 |
let |
|
|
25 | let dot_hg = working_directory.join(".hg"); | |
|
26 | Self { | |
|
27 |
|
|
|
28 |
dot_hg |
|
|
29 | working_directory, | |
|
29 | /// Search the current directory and its ancestores for a repository: | |
|
30 | /// a working directory that contains a `.hg` sub-directory. | |
|
31 | pub fn find() -> Result<Self, RepoFindError> { | |
|
32 | let current_directory = crate::utils::current_dir()?; | |
|
33 | // ancestors() is inclusive: it first yields `current_directory` as-is. | |
|
34 | for ancestor in current_directory.ancestors() { | |
|
35 | let dot_hg = ancestor.join(".hg"); | |
|
36 | if dot_hg.is_dir() { | |
|
37 | let repo = Self { | |
|
38 | store: dot_hg.join("store"), | |
|
39 | dot_hg, | |
|
40 | working_directory: ancestor.to_owned(), | |
|
41 | }; | |
|
42 | requirements::check(&repo)?; | |
|
43 | return Ok(repo); | |
|
44 | } | |
|
30 | 45 | } |
|
31 | } | |
|
32 | ||
|
33 | pub fn find() -> Result<Self, FindRootError> { | |
|
34 | find_root().map(Self::for_path) | |
|
35 | } | |
|
36 | ||
|
37 | pub fn check_requirements(&self) -> Result<(), HgError> { | |
|
38 | requirements::check(self) | |
|
46 | Err(RepoFindError::NotFoundInCurrentDirectoryOrAncestors { | |
|
47 | current_directory, | |
|
48 | }) | |
|
39 | 49 | } |
|
40 | 50 | |
|
41 | 51 | pub fn working_directory_path(&self) -> &Path { |
@@ -65,11 +75,15 b' impl Repo {' | |||
|
65 | 75 | } |
|
66 | 76 | |
|
67 | 77 | impl Vfs<'_> { |
|
78 | pub(crate) fn join(&self, relative_path: impl AsRef<Path>) -> PathBuf { | |
|
79 | self.base.join(relative_path) | |
|
80 | } | |
|
81 | ||
|
68 | 82 | pub(crate) fn read( |
|
69 | 83 | &self, |
|
70 | 84 | relative_path: impl AsRef<Path>, |
|
71 | 85 | ) -> Result<Vec<u8>, HgError> { |
|
72 |
let path = self. |
|
|
86 | let path = self.join(relative_path); | |
|
73 | 87 | std::fs::read(&path).for_file(&path) |
|
74 | 88 | } |
|
75 | 89 |
@@ -31,7 +31,6 b" impl<'a> Command for CatCommand<'a> {" | |||
|
31 | 31 | #[timed] |
|
32 | 32 | fn run(&self, ui: &Ui) -> Result<(), CommandError> { |
|
33 | 33 | let repo = Repo::find()?; |
|
34 | repo.check_requirements()?; | |
|
35 | 34 | let cwd = hg::utils::current_dir()?; |
|
36 | 35 | |
|
37 | 36 | let mut files = vec![]; |
@@ -48,7 +48,6 b" impl<'a> FilesCommand<'a> {" | |||
|
48 | 48 | impl<'a> Command for FilesCommand<'a> { |
|
49 | 49 | fn run(&self, ui: &Ui) -> Result<(), CommandError> { |
|
50 | 50 | let repo = Repo::find()?; |
|
51 | repo.check_requirements()?; | |
|
52 | 51 | if let Some(rev) = self.rev { |
|
53 | 52 | let files = |
|
54 | 53 | list_rev_tracked_files(&repo, rev).map_err(|e| (e, rev))?; |
@@ -1,8 +1,10 b'' | |||
|
1 | 1 | use crate::ui::utf8_to_local; |
|
2 | 2 | use crate::ui::UiError; |
|
3 | use hg::errors::{HgError, IoErrorContext}; | |
|
4 |
use hg:: |
|
|
3 | use format_bytes::format_bytes; | |
|
4 | use hg::errors::HgError; | |
|
5 | use hg::repo::RepoFindError; | |
|
5 | 6 | use hg::revlog::revlog::RevlogError; |
|
7 | use hg::utils::files::get_bytes_from_path; | |
|
6 | 8 | use std::convert::From; |
|
7 | 9 | |
|
8 | 10 | /// The kind of command error |
@@ -48,18 +50,18 b' impl From<UiError> for CommandError {' | |||
|
48 | 50 | } |
|
49 | 51 | } |
|
50 | 52 | |
|
51 |
impl From<Find |
|
|
52 |
fn from(err: Find |
|
|
53 | match err { | |
|
54 | FindRootError::RootNotFound(path) => CommandError::abort(format!( | |
|
55 | "no repository found in '{}' (.hg not found)!", | |
|
56 | path.display() | |
|
57 | )), | |
|
58 | FindRootError::GetCurrentDirError(error) => HgError::IoError { | |
|
59 | error, | |
|
60 | context: IoErrorContext::CurrentDir, | |
|
61 | } | |
|
62 | .into(), | |
|
53 | impl From<RepoFindError> for CommandError { | |
|
54 | fn from(error: RepoFindError) -> Self { | |
|
55 | match error { | |
|
56 | RepoFindError::NotFoundInCurrentDirectoryOrAncestors { | |
|
57 | current_directory, | |
|
58 | } => CommandError::Abort { | |
|
59 | message: format_bytes!( | |
|
60 | b"no repository found in '{}' (.hg not found)!", | |
|
61 | get_bytes_from_path(current_directory) | |
|
62 | ), | |
|
63 | }, | |
|
64 | RepoFindError::Other(error) => error.into(), | |
|
63 | 65 | } |
|
64 | 66 | } |
|
65 | 67 | } |
@@ -153,13 +153,7 b' Requirements' | |||
|
153 | 153 | [252] |
|
154 | 154 | |
|
155 | 155 | $ rhg debugrequirements |
|
156 | dotencode | |
|
157 | fncache | |
|
158 | generaldelta | |
|
159 | revlogv1 | |
|
160 | sparserevlog | |
|
161 | store | |
|
162 | indoor-pool | |
|
156 | [252] | |
|
163 | 157 | |
|
164 | 158 | $ echo -e '\xFF' >> .hg/requires |
|
165 | 159 | $ rhg debugrequirements |
|
1 | NO CONTENT: file was removed |
General Comments 0
You need to be logged in to leave comments.
Login now