D9942: rhg: add support for share-safe
SimonSapin
phabricator at mercurial-scm.org
Mon Feb 1 18:41:16 UTC 2021
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/D9942
AFFECTED FILES
rust/hg-core/src/repo.rs
rust/hg-core/src/requirements.rs
tests/test-rhg.t
CHANGE DETAILS
diff --git a/tests/test-rhg.t b/tests/test-rhg.t
--- a/tests/test-rhg.t
+++ b/tests/test-rhg.t
@@ -256,7 +256,7 @@
$ cd repo5
$ rhg files
- [252]
+ a
$ rhg cat -r 0 a
- [252]
+ a
diff --git a/rust/hg-core/src/requirements.rs b/rust/hg-core/src/requirements.rs
--- a/rust/hg-core/src/requirements.rs
+++ b/rust/hg-core/src/requirements.rs
@@ -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";
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
@@ -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 {
To: SimonSapin, #hg-reviewers
Cc: mercurial-patches, mercurial-devel
More information about the Mercurial-devel
mailing list