Skip to content

Commit

Permalink
view: add method to iterate local/remote pairs of certain remote
Browse files Browse the repository at this point in the history
This is common operation, and we don't need a map of all remote targets
to calculate push action.
  • Loading branch information
yuja committed Oct 12, 2023
1 parent 37f11c7 commit 420bf79
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 6 deletions.
9 changes: 4 additions & 5 deletions lib/src/git.rs
Original file line number Diff line number Diff line change
Expand Up @@ -563,11 +563,10 @@ fn copy_exportable_local_branches_to_remote_view(
) {
let new_local_branches = mut_repo
.view()
.branches()
.iter()
.filter_map(|(branch, branch_target)| {
let old_target = branch_target.remote_targets.get(remote_name).flatten();
let new_target = &branch_target.local_target;
.local_remote_branches(remote_name)
.filter_map(|(branch, targets)| {
let old_target = targets.remote_target;
let new_target = targets.local_target;
(!new_target.has_conflict() && old_target != new_target).then_some((branch, new_target))
})
.filter(|&(branch, _)| git_ref_filter(&RefName::LocalBranch(branch.to_owned())))
Expand Down
7 changes: 7 additions & 0 deletions lib/src/refs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,13 @@ fn find_pair_to_remove(
None
}

/// Pair of local and remote targets which usually represents a tracking branch.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct TrackingRefPair<'a> {
pub local_target: &'a RefTarget,
pub remote_target: &'a RefTarget,
}

#[derive(Debug, PartialEq, Eq, Clone, Hash)]
pub struct BranchPushUpdate {
pub old_target: Option<CommitId>,
Expand Down
26 changes: 25 additions & 1 deletion lib/src/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use crate::backend::CommitId;
use crate::index::Index;
use crate::op_store;
use crate::op_store::{BranchTarget, RefTarget, RefTargetOptionExt as _, WorkspaceId};
use crate::refs::merge_ref_targets;
use crate::refs::{merge_ref_targets, TrackingRefPair};

#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Hash, Debug)]
pub enum RefName {
Expand Down Expand Up @@ -250,6 +250,30 @@ impl View {
}
}

/// Iterates local/remote branch `(name, targets)`s of the specified remote
/// in lexicographical order.
pub fn local_remote_branches<'a>(
&'a self,
remote_name: &'a str, // TODO: migrate to per-remote view and remove 'a
) -> impl Iterator<Item = (&'a str, TrackingRefPair<'a>)> + 'a {
// TODO: maybe untracked remote_target can be translated to absent, and rename
// the method accordingly.
self.data
.branches
.iter()
.filter_map(move |(name, branch_target)| {
let local_target = &branch_target.local_target;
let remote_target = branch_target.remote_targets.get(remote_name).flatten();
(local_target.is_present() || remote_target.is_present()).then_some((
name.as_ref(),
TrackingRefPair {
local_target,
remote_target,
},
))
})
}

pub fn rename_remote(&mut self, old: &str, new: &str) {
for branch in self.data.branches.values_mut() {
let target = branch.remote_targets.remove(old).flatten();
Expand Down

0 comments on commit 420bf79

Please sign in to comment.