Mercurial > hg
changeset 46463:95b276283b67
rhg: add support for share-safe
Differential Revision: https://phab.mercurial-scm.org/D9942
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Mon, 01 Feb 2021 11:41:10 +0100 |
parents | d03b0601e0eb |
children | 0e2becd1fe0c |
files | rust/hg-core/src/repo.rs rust/hg-core/src/requirements.rs tests/test-rhg.t |
diffstat | 3 files changed, 39 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/rust/hg-core/src/repo.rs Thu Jan 14 13:04:12 2021 +0100 +++ b/rust/hg-core/src/repo.rs Mon Feb 01 11:41:10 2021 +0100 @@ -47,15 +47,34 @@ /// To be called after checking that `.hg` is a sub-directory fn new_at_path(working_directory: PathBuf) -> Result<Self, HgError> { let dot_hg = working_directory.join(".hg"); + let hg_vfs = Vfs { base: &dot_hg }; - let reqs = requirements::load_if_exists(hg_vfs)?; + let mut reqs = requirements::load_if_exists(hg_vfs)?; let relative = reqs.contains(requirements::RELATIVE_SHARED_REQUIREMENT); let shared = reqs.contains(requirements::SHARED_REQUIREMENT) || relative; + + // From `mercurial/localrepo.py`: + // + // if .hg/requires contains the sharesafe requirement, it means + // there exists a `.hg/store/requires` too and we should read it + // NOTE: presence of SHARESAFE_REQUIREMENT imply that store requirement + // is present. We never write SHARESAFE_REQUIREMENT for a repo if store + // is not present, refer checkrequirementscompat() for that + // + // However, if SHARESAFE_REQUIREMENT is not present, it means that the + // repository was shared the old way. We check the share source + // .hg/requires for SHARESAFE_REQUIREMENT to detect whether the + // current repository needs to be reshared + let share_safe = reqs.contains(requirements::SHARESAFE_REQUIREMENT); + let store_path; if !shared { store_path = dot_hg.join("store"); + if share_safe { + reqs.extend(requirements::load(Vfs { base: &store_path })?); + } } else { let bytes = hg_vfs.read("sharedpath")?; let mut shared_path = get_path_from_bytes(&bytes).to_owned(); @@ -70,6 +89,17 @@ } store_path = shared_path.join("store"); + + let source_is_share_safe = + 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")); + } else if source_is_share_safe && !share_safe { + return Err(HgError::unsupported("share-safe upgrade")); + } } let repo = Self {
--- a/rust/hg-core/src/requirements.rs Thu Jan 14 13:04:12 2021 +0100 +++ b/rust/hg-core/src/requirements.rs Mon Feb 01 11:41:10 2021 +0100 @@ -22,6 +22,10 @@ .collect() } +pub(crate) fn load(hg_vfs: Vfs) -> Result<HashSet<String>, HgError> { + parse(&hg_vfs.read("requires")?) +} + pub(crate) fn load_if_exists(hg_vfs: Vfs) -> Result<HashSet<String>, HgError> { if let Some(bytes) = hg_vfs.read("requires").io_not_found_as_none()? { parse(&bytes) @@ -58,6 +62,7 @@ "generaldelta", "revlogv1", SHARED_REQUIREMENT, + SHARESAFE_REQUIREMENT, SPARSEREVLOG_REQUIREMENT, RELATIVE_SHARED_REQUIREMENT, "store", @@ -130,4 +135,4 @@ /// store and working copy requirements i.e. both `.hg/requires` and /// `.hg/store/requires` are present. #[allow(unused)] -pub(crate) const SHARESAFE_REQUIREMENT: &str = "exp-sharesafe"; +pub(crate) const SHARESAFE_REQUIREMENT: &str = "share-safe";