Show More
@@ -8,7 +8,9 b' pub enum HgError {' | |||||
8 | context: IoErrorContext, |
|
8 | context: IoErrorContext, | |
9 | }, |
|
9 | }, | |
10 |
|
10 | |||
11 | /// A file under `.hg/` normally only written by Mercurial |
|
11 | /// A file under `.hg/` normally only written by Mercurial is not in the | |
|
12 | /// expected format. This indicates a bug in Mercurial, filesystem | |||
|
13 | /// corruption, or hardware failure. | |||
12 | /// |
|
14 | /// | |
13 | /// The given string is a short explanation for users, not intended to be |
|
15 | /// The given string is a short explanation for users, not intended to be | |
14 | /// machine-readable. |
|
16 | /// machine-readable. | |
@@ -21,6 +23,12 b' pub enum HgError {' | |||||
21 | /// The given string is a short explanation for users, not intended to be |
|
23 | /// The given string is a short explanation for users, not intended to be | |
22 | /// machine-readable. |
|
24 | /// machine-readable. | |
23 | UnsupportedFeature(String), |
|
25 | UnsupportedFeature(String), | |
|
26 | ||||
|
27 | /// Operation cannot proceed for some other reason. | |||
|
28 | /// | |||
|
29 | /// The given string is a short explanation for users, not intended to be | |||
|
30 | /// machine-readable. | |||
|
31 | Abort(String), | |||
24 | } |
|
32 | } | |
25 |
|
33 | |||
26 | /// Details about where an I/O error happened |
|
34 | /// Details about where an I/O error happened | |
@@ -46,6 +54,9 b' impl HgError {' | |||||
46 | pub fn unsupported(explanation: impl Into<String>) -> Self { |
|
54 | pub fn unsupported(explanation: impl Into<String>) -> Self { | |
47 | HgError::UnsupportedFeature(explanation.into()) |
|
55 | HgError::UnsupportedFeature(explanation.into()) | |
48 | } |
|
56 | } | |
|
57 | pub fn abort(explanation: impl Into<String>) -> Self { | |||
|
58 | HgError::Abort(explanation.into()) | |||
|
59 | } | |||
49 | } |
|
60 | } | |
50 |
|
61 | |||
51 | // TODO: use `DisplayBytes` instead to show non-Unicode filenames losslessly? |
|
62 | // TODO: use `DisplayBytes` instead to show non-Unicode filenames losslessly? | |
@@ -61,6 +72,7 b' impl fmt::Display for HgError {' | |||||
61 | HgError::UnsupportedFeature(explanation) => { |
|
72 | HgError::UnsupportedFeature(explanation) => { | |
62 | write!(f, "unsupported feature: {}", explanation) |
|
73 | write!(f, "unsupported feature: {}", explanation) | |
63 | } |
|
74 | } | |
|
75 | HgError::Abort(explanation) => explanation.fmt(f), | |||
64 | } |
|
76 | } | |
65 | } |
|
77 | } | |
66 | } |
|
78 | } |
@@ -32,12 +32,12 b" pub(crate) struct Vfs<'a> {" | |||||
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( |
|
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 { | |
@@ -46,7 +46,10 b' impl Repo {' | |||||
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 }; | |
@@ -95,11 +98,23 b' impl Repo {' | |||||
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 |
General Comments 0
You need to be logged in to leave comments.
Login now