diff --git a/lib/src/revset.rs b/lib/src/revset.rs index ce67dc710..401b8f882 100644 --- a/lib/src/revset.rs +++ b/lib/src/revset.rs @@ -2135,9 +2135,9 @@ fn resolve_commit_ref( RevsetCommitRef::VisibleHeads => Ok(repo.view().heads().iter().cloned().collect_vec()), RevsetCommitRef::Root => Ok(vec![repo.store().root_commit_id().clone()]), RevsetCommitRef::Branches(pattern) => { - let view_data = repo.view().store_view(); - let commit_ids = pattern - .filter_btree_map(&view_data.local_branches) + let commit_ids = repo + .view() + .local_branches_matching(pattern) .flat_map(|(_, target)| target.added_ids()) .cloned() .collect(); @@ -2147,10 +2147,9 @@ fn resolve_commit_ref( branch_pattern, remote_pattern, } => { - let view_data = repo.view().store_view(); - let commit_ids = remote_pattern - .filter_btree_map(&view_data.remote_views) - .flat_map(|(_, remote_view)| branch_pattern.filter_btree_map(&remote_view.branches)) + let commit_ids = repo + .view() + .remote_branches_matching(branch_pattern, remote_pattern) .flat_map(|(_, remote_ref)| remote_ref.target.added_ids()) .cloned() .collect(); diff --git a/lib/src/view.rs b/lib/src/view.rs index 1d67d3d6c..beb9a0b20 100644 --- a/lib/src/view.rs +++ b/lib/src/view.rs @@ -26,6 +26,7 @@ use crate::op_store::{ BranchTarget, RefTarget, RefTargetOptionExt as _, RemoteRef, RemoteRefState, WorkspaceId, }; use crate::refs::{merge_ref_targets, TrackingRefPair}; +use crate::str_util::StringPattern; #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Hash, Debug)] pub enum RefName { @@ -180,6 +181,17 @@ impl View { .map(|(name, target)| (name.as_ref(), target)) } + /// Iterates local branch `(name, target)`s matching the given pattern. + /// Entries are sorted by `name`. + pub fn local_branches_matching<'a: 'b, 'b>( + &'a self, + pattern: &'b StringPattern, + ) -> impl Iterator + 'b { + pattern + .filter_btree_map(&self.data.local_branches) + .map(|(name, target)| (name.as_ref(), target)) + } + pub fn get_local_branch(&self, name: &str) -> &RefTarget { self.data.local_branches.get(name).flatten() } @@ -215,6 +227,27 @@ impl View { .flatten() } + /// Iterates remote branch `((name, remote_name), remote_ref)`s matching the + /// given patterns. Entries are sorted by `(name, remote_name)`. + pub fn remote_branches_matching<'a: 'b, 'b>( + &'a self, + branch_pattern: &'b StringPattern, + remote_pattern: &'b StringPattern, + ) -> impl Iterator + 'b { + // Use kmerge instead of flat_map for consistency with all_remote_branches(). + remote_pattern + .filter_btree_map(&self.data.remote_views) + .map(|(remote_name, remote_view)| { + branch_pattern.filter_btree_map(&remote_view.branches).map( + |(branch_name, remote_ref)| { + let full_name = (branch_name.as_ref(), remote_name.as_ref()); + (full_name, remote_ref) + }, + ) + }) + .kmerge_by(|(full_name1, _), (full_name2, _)| full_name1 < full_name2) + } + pub fn get_remote_branch(&self, name: &str, remote_name: &str) -> &RemoteRef { if let Some(remote_view) = self.data.remote_views.get(remote_name) { remote_view.branches.get(name).flatten()