Mercurial > hg
changeset 52048:78fc666a3e94
rust-files: check for empty manifests caused by narrow
Explanations inline
author | Raphaël Gomès <rgomes@octobus.net> |
---|---|
date | Wed, 02 Oct 2024 13:39:43 +0200 |
parents | e1fe336c007a |
children | a8cf6a852f11 |
files | rust/hg-core/src/operations/list_tracked_files.rs rust/hg-core/src/revlog/manifest.rs |
diffstat | 2 files changed, 30 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/rust/hg-core/src/operations/list_tracked_files.rs Wed Oct 02 13:36:51 2024 +0200 +++ b/rust/hg-core/src/operations/list_tracked_files.rs Wed Oct 02 13:39:43 2024 +0200 @@ -8,7 +8,7 @@ use std::num::NonZeroU8; use crate::errors::HgError; -use crate::matchers::Matcher; +use crate::matchers::{Matcher, VisitChildrenSet}; use crate::repo::Repo; use crate::revlog::manifest::Manifest; use crate::revlog::RevlogError; @@ -23,10 +23,7 @@ narrow_matcher: Box<dyn Matcher + Sync>, ) -> Result<FilesForRev, RevlogError> { let rev = crate::revset::resolve_single(revset, repo)?; - Ok(FilesForRev { - manifest: repo.manifest_for_rev(rev.into())?, - narrow_matcher, - }) + list_rev_tracked_files(repo, rev.into(), narrow_matcher) } /// List files under Mercurial control at a given revision. @@ -35,8 +32,30 @@ rev: UncheckedRevision, narrow_matcher: Box<dyn Matcher + Sync>, ) -> Result<FilesForRev, RevlogError> { + // TODO move this to the repo itself + // This implies storing the narrow matcher in the repo, bubbling up the + // errors and warnings, so it's a bit of churn. In the meantime, the repo + // method will error out on narrowed manifests. + let manifest = match repo.manifest_for_rev(rev) { + Ok(manifest) => manifest, + Err(e) => match e { + RevlogError::InvalidRevision(_) => { + let outside_of_current_narrow_spec = narrow_matcher + .visit_children_set(HgPath::new("")) + == VisitChildrenSet::Empty; + if outside_of_current_narrow_spec { + // Fake a manifest for a manifest whose node is known, but + // which doesn't exist because it's empty after narrowing + Manifest::empty() + } else { + return Err(e); + } + } + _ => return Err(e), + }, + }; Ok(FilesForRev { - manifest: repo.manifest_for_rev(rev)?, + manifest, narrow_matcher, }) }
--- a/rust/hg-core/src/revlog/manifest.rs Wed Oct 02 13:36:51 2024 +0200 +++ b/rust/hg-core/src/revlog/manifest.rs Wed Oct 02 13:39:43 2024 +0200 @@ -87,6 +87,11 @@ } impl Manifest { + /// Return a new empty manifest + pub fn empty() -> Self { + Self { bytes: vec![] } + } + pub fn iter( &self, ) -> impl Iterator<Item = Result<ManifestEntry, HgError>> {