Patchwork D9963: rhg: Abort based on config on share-safe mismatch

login
register
mail settings
Submitter phabricator
Date Feb. 5, 2021, 9:26 a.m.
Message ID <differential-rev-PHID-DREV-byv5zww6jfahxh6i6zrx-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/48276/
State Superseded
Headers show

Comments

phabricator - Feb. 5, 2021, 9:26 a.m.
SimonSapin created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D9963

AFFECTED FILES
  rust/hg-core/src/errors.rs
  rust/hg-core/src/repo.rs

CHANGE DETAILS




To: SimonSapin, #hg-reviewers
Cc: mercurial-patches, mercurial-devel

Patch

diff --git a/rust/hg-core/src/repo.rs b/rust/hg-core/src/repo.rs
--- a/rust/hg-core/src/repo.rs
+++ b/rust/hg-core/src/repo.rs
@@ -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"),
+                    },
+                );
             }
         }
 
diff --git a/rust/hg-core/src/errors.rs b/rust/hg-core/src/errors.rs
--- a/rust/hg-core/src/errors.rs
+++ b/rust/hg-core/src/errors.rs
@@ -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),
         }
     }
 }