# HG changeset patch # User Raphaël Gomès # Date 2023-01-11 16:30:55 # Node ID e57f76c28f7b06cd9a341bd72101b4bf50aa6c1d # Parent df9eabc9837b5eecdf0d8d47b053799ed98174eb rhg-files: add support for narrow when specifying a revision This makes it so that `rhg files -r NODE` works properly when using narrow. diff --git a/rust/hg-core/src/operations/list_tracked_files.rs b/rust/hg-core/src/operations/list_tracked_files.rs --- a/rust/hg-core/src/operations/list_tracked_files.rs +++ b/rust/hg-core/src/operations/list_tracked_files.rs @@ -6,24 +6,40 @@ // GNU General Public License version 2 or any later version. use crate::errors::HgError; +use crate::matchers::Matcher; use crate::repo::Repo; use crate::revlog::manifest::Manifest; use crate::revlog::RevlogError; +use crate::utils::filter_map_results; use crate::utils::hg_path::HgPath; /// List files under Mercurial control at a given revision. pub fn list_rev_tracked_files( repo: &Repo, revset: &str, + narrow_matcher: Box, ) -> Result { let rev = crate::revset::resolve_single(revset, repo)?; - Ok(FilesForRev(repo.manifest_for_rev(rev)?)) + Ok(FilesForRev { + manifest: repo.manifest_for_rev(rev)?, + narrow_matcher, + }) } -pub struct FilesForRev(Manifest); +pub struct FilesForRev { + manifest: Manifest, + narrow_matcher: Box, +} impl FilesForRev { pub fn iter(&self) -> impl Iterator> { - self.0.iter().map(|entry| Ok(entry?.path)) + filter_map_results(self.manifest.iter(), |entry| { + let path = entry.path; + Ok(if self.narrow_matcher.matches(path) { + Some(path) + } else { + None + }) + }) } } diff --git a/rust/rhg/src/commands/files.rs b/rust/rhg/src/commands/files.rs --- a/rust/rhg/src/commands/files.rs +++ b/rust/rhg/src/commands/files.rs @@ -51,24 +51,15 @@ pub fn run(invocation: &crate::CliInvoca )); } + let (narrow_matcher, narrow_warnings) = narrow::matcher(repo)?; + print_narrow_sparse_warnings(&narrow_warnings, &[], invocation.ui, repo)?; + if let Some(rev) = rev { - if repo.has_narrow() { - return Err(CommandError::unsupported( - "rhg files -r is not supported in narrow clones", - )); - } - let files = list_rev_tracked_files(repo, rev) + let files = list_rev_tracked_files(repo, rev, narrow_matcher) .map_err(|e| (e, rev.as_ref()))?; display_files(invocation.ui, repo, files.iter()) } else { // The dirstate always reflects the sparse narrowspec. - let (narrow_matcher, narrow_warnings) = narrow::matcher(repo)?; - print_narrow_sparse_warnings( - &narrow_warnings, - &[], - invocation.ui, - repo, - )?; let dirstate = repo.dirstate_map()?; let files_res: Result, _> = filter_map_results(dirstate.iter(), |(path, entry)| { diff --git a/tests/test-rhg-sparse-narrow.t b/tests/test-rhg-sparse-narrow.t --- a/tests/test-rhg-sparse-narrow.t +++ b/tests/test-rhg-sparse-narrow.t @@ -75,12 +75,12 @@ TODO: bad error message $ "$real_hg" cat -r "$tip" hide [1] -A naive implementation of [rhg files] leaks the paths that are supposed to be -hidden by narrow, so we just fall back to hg when accessing a revision. +A naive implementation of `rhg files` would leak the paths that are supposed +to be hidden by narrow. $ $NO_FALLBACK rhg files -r "$tip" - unsupported feature: rhg files -r is not supported in narrow clones - [252] + dir1/x + dir1/y $ "$real_hg" files -r "$tip" dir1/x dir1/y