Mercurial > public > mercurial-scm > hg-stable
diff rust/hg-core/src/requirements.rs @ 46524:d03b0601e0eb
rhg: initial support for shared repositories
Differential Revision: https://phab.mercurial-scm.org/D9941
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Thu, 14 Jan 2021 13:04:12 +0100 |
parents | 43d63979a75e |
children | 95b276283b67 |
line wrap: on
line diff
--- a/rust/hg-core/src/requirements.rs Mon Feb 01 19:30:28 2021 +0100 +++ b/rust/hg-core/src/requirements.rs Thu Jan 14 13:04:12 2021 +0100 @@ -1,7 +1,8 @@ use crate::errors::{HgError, HgResultExt}; -use crate::repo::Repo; +use crate::repo::{Repo, Vfs}; +use std::collections::HashSet; -fn parse(bytes: &[u8]) -> Result<Vec<String>, HgError> { +fn parse(bytes: &[u8]) -> Result<HashSet<String>, HgError> { // The Python code reading this file uses `str.splitlines` // which looks for a number of line separators (even including a couple of // non-ASCII ones), but Python code writing it always uses `\n`. @@ -21,10 +22,8 @@ .collect() } -pub fn load(repo: &Repo) -> Result<Vec<String>, HgError> { - if let Some(bytes) = - repo.hg_vfs().read("requires").io_not_found_as_none()? - { +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) } else { // Treat a missing file the same as an empty file. @@ -34,13 +33,13 @@ // > the repository. This file was introduced in Mercurial 0.9.2, // > which means very old repositories may not have one. We assume // > a missing file translates to no requirements. - Ok(Vec::new()) + Ok(HashSet::new()) } } -pub fn check(repo: &Repo) -> Result<(), HgError> { - for feature in load(repo)? { - if !SUPPORTED.contains(&&*feature) { +pub(crate) fn check(repo: &Repo) -> Result<(), HgError> { + for feature in repo.requirements() { + if !SUPPORTED.contains(&feature.as_str()) { // TODO: collect and all unknown features and include them in the // error message? return Err(HgError::UnsupportedFeature(format!( @@ -58,10 +57,77 @@ "fncache", "generaldelta", "revlogv1", - "sparserevlog", + SHARED_REQUIREMENT, + SPARSEREVLOG_REQUIREMENT, + RELATIVE_SHARED_REQUIREMENT, "store", // As of this writing everything rhg does is read-only. // When it starts writing to the repository, it’ll need to either keep the // persistent nodemap up to date or remove this entry: "persistent-nodemap", ]; + +// Copied from mercurial/requirements.py: + +/// When narrowing is finalized and no longer subject to format changes, +/// we should move this to just "narrow" or similar. +#[allow(unused)] +pub(crate) const NARROW_REQUIREMENT: &str = "narrowhg-experimental"; + +/// Enables sparse working directory usage +#[allow(unused)] +pub(crate) const SPARSE_REQUIREMENT: &str = "exp-sparse"; + +/// Enables the internal phase which is used to hide changesets instead +/// of stripping them +#[allow(unused)] +pub(crate) const INTERNAL_PHASE_REQUIREMENT: &str = "internal-phase"; + +/// Stores manifest in Tree structure +#[allow(unused)] +pub(crate) const TREEMANIFEST_REQUIREMENT: &str = "treemanifest"; + +/// Increment the sub-version when the revlog v2 format changes to lock out old +/// clients. +#[allow(unused)] +pub(crate) const REVLOGV2_REQUIREMENT: &str = "exp-revlogv2.1"; + +/// A repository with the sparserevlog feature will have delta chains that +/// can spread over a larger span. Sparse reading cuts these large spans into +/// pieces, so that each piece isn't too big. +/// Without the sparserevlog capability, reading from the repository could use +/// huge amounts of memory, because the whole span would be read at once, +/// including all the intermediate revisions that aren't pertinent for the +/// chain. This is why once a repository has enabled sparse-read, it becomes +/// required. +#[allow(unused)] +pub(crate) const SPARSEREVLOG_REQUIREMENT: &str = "sparserevlog"; + +/// A repository with the sidedataflag requirement will allow to store extra +/// information for revision without altering their original hashes. +#[allow(unused)] +pub(crate) const SIDEDATA_REQUIREMENT: &str = "exp-sidedata-flag"; + +/// A repository with the the copies-sidedata-changeset requirement will store +/// copies related information in changeset's sidedata. +#[allow(unused)] +pub(crate) const COPIESSDC_REQUIREMENT: &str = "exp-copies-sidedata-changeset"; + +/// The repository use persistent nodemap for the changelog and the manifest. +#[allow(unused)] +pub(crate) const NODEMAP_REQUIREMENT: &str = "persistent-nodemap"; + +/// Denotes that the current repository is a share +#[allow(unused)] +pub(crate) const SHARED_REQUIREMENT: &str = "shared"; + +/// Denotes that current repository is a share and the shared source path is +/// relative to the current repository root path +#[allow(unused)] +pub(crate) const RELATIVE_SHARED_REQUIREMENT: &str = "relshared"; + +/// A repository with share implemented safely. The repository has different +/// 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";