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