30 } |
30 } |
31 |
31 |
32 impl Repo { |
32 impl Repo { |
33 /// Search the current directory and its ancestores for a repository: |
33 /// Search the current directory and its ancestores for a repository: |
34 /// a working directory that contains a `.hg` sub-directory. |
34 /// a working directory that contains a `.hg` sub-directory. |
35 pub fn find(_config: &Config) -> Result<Self, RepoFindError> { |
35 pub fn find(config: &Config) -> Result<Self, RepoFindError> { |
36 let current_directory = crate::utils::current_dir()?; |
36 let current_directory = crate::utils::current_dir()?; |
37 // ancestors() is inclusive: it first yields `current_directory` as-is. |
37 // ancestors() is inclusive: it first yields `current_directory` as-is. |
38 for ancestor in current_directory.ancestors() { |
38 for ancestor in current_directory.ancestors() { |
39 if ancestor.join(".hg").is_dir() { |
39 if ancestor.join(".hg").is_dir() { |
40 return Ok(Self::new_at_path(ancestor.to_owned())?); |
40 return Ok(Self::new_at_path(ancestor.to_owned(), config)?); |
41 } |
41 } |
42 } |
42 } |
43 Err(RepoFindError::NotFoundInCurrentDirectoryOrAncestors { |
43 Err(RepoFindError::NotFoundInCurrentDirectoryOrAncestors { |
44 current_directory, |
44 current_directory, |
45 }) |
45 }) |
46 } |
46 } |
47 |
47 |
48 /// To be called after checking that `.hg` is a sub-directory |
48 /// To be called after checking that `.hg` is a sub-directory |
49 fn new_at_path(working_directory: PathBuf) -> Result<Self, HgError> { |
49 fn new_at_path( |
|
50 working_directory: PathBuf, |
|
51 config: &Config, |
|
52 ) -> Result<Self, HgError> { |
50 let dot_hg = working_directory.join(".hg"); |
53 let dot_hg = working_directory.join(".hg"); |
51 |
54 |
52 let hg_vfs = Vfs { base: &dot_hg }; |
55 let hg_vfs = Vfs { base: &dot_hg }; |
53 let mut reqs = requirements::load_if_exists(hg_vfs)?; |
56 let mut reqs = requirements::load_if_exists(hg_vfs)?; |
54 let relative = |
57 let relative = |
93 |
96 |
94 let source_is_share_safe = |
97 let source_is_share_safe = |
95 requirements::load(Vfs { base: &shared_path })? |
98 requirements::load(Vfs { base: &shared_path })? |
96 .contains(requirements::SHARESAFE_REQUIREMENT); |
99 .contains(requirements::SHARESAFE_REQUIREMENT); |
97 |
100 |
98 // TODO: support for `share.safe-mismatch.*` config |
|
99 if share_safe && !source_is_share_safe { |
101 if share_safe && !source_is_share_safe { |
100 return Err(HgError::unsupported("share-safe downgrade")); |
102 return Err(match config.get(b"safe-mismatch", b"source-not-safe") { |
|
103 Some(b"abort") | None => HgError::abort( |
|
104 "share source does not support share-safe requirement" |
|
105 ), |
|
106 _ => HgError::unsupported("share-safe downgrade") |
|
107 }); |
101 } else if source_is_share_safe && !share_safe { |
108 } else if source_is_share_safe && !share_safe { |
102 return Err(HgError::unsupported("share-safe upgrade")); |
109 return Err( |
|
110 match config.get(b"safe-mismatch", b"source-safe") { |
|
111 Some(b"abort") | None => HgError::abort( |
|
112 "version mismatch: source uses share-safe \ |
|
113 functionality while the current share does not", |
|
114 ), |
|
115 _ => HgError::unsupported("share-safe upgrade"), |
|
116 }, |
|
117 ); |
103 } |
118 } |
104 } |
119 } |
105 |
120 |
106 let repo = Self { |
121 let repo = Self { |
107 requirements: reqs, |
122 requirements: reqs, |