1 use crate::config::{Config, ConfigError, ConfigParseError}; |
1 use crate::config::{Config, ConfigError, ConfigParseError}; |
2 use crate::errors::{HgError, IoResultExt}; |
2 use crate::errors::{HgError, IoResultExt}; |
3 use crate::requirements; |
3 use crate::requirements; |
|
4 use crate::utils::current_dir; |
4 use crate::utils::files::get_path_from_bytes; |
5 use crate::utils::files::get_path_from_bytes; |
5 use memmap::{Mmap, MmapOptions}; |
6 use memmap::{Mmap, MmapOptions}; |
6 use std::collections::HashSet; |
7 use std::collections::HashSet; |
7 use std::path::{Path, PathBuf}; |
8 use std::path::{Path, PathBuf}; |
8 |
9 |
42 } |
43 } |
43 |
44 |
44 impl Repo { |
45 impl Repo { |
45 /// Search the current directory and its ancestores for a repository: |
46 /// Search the current directory and its ancestores for a repository: |
46 /// a working directory that contains a `.hg` sub-directory. |
47 /// a working directory that contains a `.hg` sub-directory. |
47 pub fn find(config: &Config) -> Result<Self, RepoError> { |
48 /// |
48 let current_directory = crate::utils::current_dir()?; |
49 /// `explicit_path` is for `--repository` command-line arguments. |
49 // ancestors() is inclusive: it first yields `current_directory` as-is. |
50 pub fn find( |
50 for ancestor in current_directory.ancestors() { |
51 config: &Config, |
51 if ancestor.join(".hg").is_dir() { |
52 explicit_path: Option<&Path>, |
52 return Ok(Self::new_at_path(ancestor.to_owned(), config)?); |
53 ) -> Result<Self, RepoError> { |
53 } |
54 if let Some(root) = explicit_path { |
54 } |
55 // Having an absolute path isn’t necessary here but can help code |
55 Err(RepoError::NotFound { current_directory }) |
56 // elsewhere |
|
57 let root = current_dir()?.join(root); |
|
58 if root.join(".hg").is_dir() { |
|
59 Self::new_at_path(root, config) |
|
60 } else { |
|
61 Err(RepoError::NotFound { |
|
62 at: root.to_owned(), |
|
63 }) |
|
64 } |
|
65 } else { |
|
66 let current_directory = crate::utils::current_dir()?; |
|
67 // ancestors() is inclusive: it first yields `current_directory` |
|
68 // as-is. |
|
69 for ancestor in current_directory.ancestors() { |
|
70 if ancestor.join(".hg").is_dir() { |
|
71 return Self::new_at_path(ancestor.to_owned(), config); |
|
72 } |
|
73 } |
|
74 Err(RepoError::NotFound { |
|
75 at: current_directory, |
|
76 }) |
|
77 } |
56 } |
78 } |
57 |
79 |
58 /// To be called after checking that `.hg` is a sub-directory |
80 /// To be called after checking that `.hg` is a sub-directory |
59 fn new_at_path( |
81 fn new_at_path( |
60 working_directory: PathBuf, |
82 working_directory: PathBuf, |