Mercurial > public > mercurial-scm > hg
diff rust/rhg/src/main.rs @ 49192:2ab79873786e
auto-upgrade: introduce a way to auto-upgrade to/from share-safe
This is the first "automatic-upgrade" capability. In the following commits,
similar features are coming for other "fast to upgrade" formats.
This is different from the `safe-mismatch.source-not-safe` and
`safe-mismatch.source-safe` configuration that deal with mismatch between a
share and its share-source. Here we are dealing with mismatch between a
repository configuration and its actual format.
We will need further work for cases were the repository cannot be locked. A
basic protection is in place to avoid a infinite loop for now, but it will get
proper attention in a later changeset.
Differential Revision: https://phab.mercurial-scm.org/D12611
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Tue, 05 Apr 2022 05:19:47 +0200 |
parents | a932cad26d37 |
children | e4b31016e194 |
line wrap: on
line diff
--- a/rust/rhg/src/main.rs Fri Apr 15 22:02:07 2022 +0200 +++ b/rust/rhg/src/main.rs Tue Apr 05 05:19:47 2022 +0200 @@ -7,10 +7,10 @@ use clap::ArgMatches; use format_bytes::{format_bytes, join}; use hg::config::{Config, ConfigSource}; -use hg::exit_codes; use hg::repo::{Repo, RepoError}; use hg::utils::files::{get_bytes_from_os_str, get_path_from_bytes}; use hg::utils::SliceExt; +use hg::{exit_codes, requirements}; use std::collections::HashSet; use std::ffi::OsString; use std::os::unix::prelude::CommandExt; @@ -724,6 +724,50 @@ } } +/// Array of tuples of (auto upgrade conf, feature conf, local requirement) +const AUTO_UPGRADES: &[((&str, &str), (&str, &str), &str)] = &[ + ( + ("format", "use-share-safe.automatic-upgrade-of-mismatching-repositories"), + ("format", "use-share-safe"), + requirements::SHARESAFE_REQUIREMENT, + ), +]; + +/// Mercurial allows users to automatically upgrade their repository. +/// `rhg` does not have the ability to upgrade yet, so fallback if an upgrade +/// is needed. +fn check_auto_upgrade( + config: &Config, + reqs: &HashSet<String>, +) -> Result<(), CommandError> { + for (upgrade_conf, feature_conf, local_req) in AUTO_UPGRADES.iter() { + let auto_upgrade = config + .get_bool(upgrade_conf.0.as_bytes(), upgrade_conf.1.as_bytes())?; + + if auto_upgrade { + let want_it = config.get_bool( + feature_conf.0.as_bytes(), + feature_conf.1.as_bytes(), + )?; + let have_it = reqs.contains(*local_req); + + let action = match (want_it, have_it) { + (true, false) => Some("upgrade"), + (false, true) => Some("downgrade"), + _ => None, + }; + if let Some(action) = action { + let message = format!( + "automatic {} {}.{}", + action, upgrade_conf.0, upgrade_conf.1 + ); + return Err(CommandError::unsupported(message)); + } + } + } + Ok(()) +} + fn check_unsupported( config: &Config, repo: Result<&Repo, &NoRepoInCwdError>, @@ -740,6 +784,7 @@ if repo.has_subrepos()? { Err(CommandError::unsupported("sub-repositories"))? } + check_auto_upgrade(config, repo.requirements())?; } if config.has_non_empty_section(b"encode") {