rhg: Abort based on config on share-safe mismatch
Differential Revision: https://phab.mercurial-scm.org/D9963
--- a/rust/hg-core/src/errors.rs Thu Feb 04 13:17:55 2021 +0100
+++ b/rust/hg-core/src/errors.rs Thu Feb 04 14:29:47 2021 +0100
@@ -8,7 +8,9 @@
context: IoErrorContext,
},
- /// A file under `.hg/` normally only written by Mercurial
+ /// A file under `.hg/` normally only written by Mercurial is not in the
+ /// expected format. This indicates a bug in Mercurial, filesystem
+ /// corruption, or hardware failure.
///
/// The given string is a short explanation for users, not intended to be
/// machine-readable.
@@ -21,6 +23,12 @@
/// The given string is a short explanation for users, not intended to be
/// machine-readable.
UnsupportedFeature(String),
+
+ /// Operation cannot proceed for some other reason.
+ ///
+ /// The given string is a short explanation for users, not intended to be
+ /// machine-readable.
+ Abort(String),
}
/// Details about where an I/O error happened
@@ -46,6 +54,9 @@
pub fn unsupported(explanation: impl Into<String>) -> Self {
HgError::UnsupportedFeature(explanation.into())
}
+ pub fn abort(explanation: impl Into<String>) -> Self {
+ HgError::Abort(explanation.into())
+ }
}
// TODO: use `DisplayBytes` instead to show non-Unicode filenames losslessly?
@@ -61,6 +72,7 @@
HgError::UnsupportedFeature(explanation) => {
write!(f, "unsupported feature: {}", explanation)
}
+ HgError::Abort(explanation) => explanation.fmt(f),
}
}
}
--- a/rust/hg-core/src/repo.rs Thu Feb 04 13:17:55 2021 +0100
+++ b/rust/hg-core/src/repo.rs Thu Feb 04 14:29:47 2021 +0100
@@ -32,12 +32,12 @@
impl Repo {
/// Search the current directory and its ancestores for a repository:
/// a working directory that contains a `.hg` sub-directory.
- pub fn find(_config: &Config) -> Result<Self, RepoFindError> {
+ pub fn find(config: &Config) -> Result<Self, RepoFindError> {
let current_directory = crate::utils::current_dir()?;
// ancestors() is inclusive: it first yields `current_directory` as-is.
for ancestor in current_directory.ancestors() {
if ancestor.join(".hg").is_dir() {
- return Ok(Self::new_at_path(ancestor.to_owned())?);
+ return Ok(Self::new_at_path(ancestor.to_owned(), config)?);
}
}
Err(RepoFindError::NotFoundInCurrentDirectoryOrAncestors {
@@ -46,7 +46,10 @@
}
/// To be called after checking that `.hg` is a sub-directory
- fn new_at_path(working_directory: PathBuf) -> Result<Self, HgError> {
+ fn new_at_path(
+ working_directory: PathBuf,
+ config: &Config,
+ ) -> Result<Self, HgError> {
let dot_hg = working_directory.join(".hg");
let hg_vfs = Vfs { base: &dot_hg };
@@ -95,11 +98,23 @@
requirements::load(Vfs { base: &shared_path })?
.contains(requirements::SHARESAFE_REQUIREMENT);
- // TODO: support for `share.safe-mismatch.*` config
if share_safe && !source_is_share_safe {
- return Err(HgError::unsupported("share-safe downgrade"));
+ return Err(match config.get(b"safe-mismatch", b"source-not-safe") {
+ Some(b"abort") | None => HgError::abort(
+ "share source does not support share-safe requirement"
+ ),
+ _ => HgError::unsupported("share-safe downgrade")
+ });
} else if source_is_share_safe && !share_safe {
- return Err(HgError::unsupported("share-safe upgrade"));
+ return Err(
+ match config.get(b"safe-mismatch", b"source-safe") {
+ Some(b"abort") | None => HgError::abort(
+ "version mismatch: source uses share-safe \
+ functionality while the current share does not",
+ ),
+ _ => HgError::unsupported("share-safe upgrade"),
+ },
+ );
}
}