ok/jj
1
0
Fork 0
forked from mirrors/jj

view: turn BranchTarget into borrowed type

This isn't important, but I'm going to change remote_targets to store RemoteRef
instead of RefTarget, so I went ahead and change the other field types as well.
This commit is contained in:
Yuya Nishihara 2023-10-12 18:54:52 +09:00
parent 92facbf21a
commit e7d93e5bf1
8 changed files with 69 additions and 77 deletions

View file

@ -389,28 +389,20 @@ fn cmd_branch_list(
.map_or(true, |branch_names| branch_names.contains(name))
});
for (name, branch_target) in branches_to_list {
let found_non_git_remote = {
let pseudo_remote_count = branch_target
.remote_targets
.contains_key(git::REMOTE_NAME_FOR_LOCAL_GIT_REPO)
as usize;
branch_target.remote_targets.len() - pseudo_remote_count > 0
};
write!(formatter.labeled("branch"), "{name}")?;
if branch_target.local_target.is_present() {
print_branch_target(formatter, &branch_target.local_target)?;
print_branch_target(formatter, branch_target.local_target)?;
} else {
writeln!(formatter, " (deleted)")?;
}
for (remote, remote_target) in branch_target.remote_targets.iter() {
if remote_target == &branch_target.local_target {
for &(remote, remote_target) in &branch_target.remote_targets {
if remote_target == branch_target.local_target {
continue;
}
write!(formatter, " ")?;
write!(formatter.labeled("branch"), "@{remote}")?;
let local_target = &branch_target.local_target;
let local_target = branch_target.local_target;
if local_target.is_present() {
let remote_added_ids = remote_target.added_ids().cloned().collect_vec();
let local_added_ids = local_target.added_ids().cloned().collect_vec();
@ -434,6 +426,10 @@ fn cmd_branch_list(
}
if branch_target.local_target.is_absent() {
let found_non_git_remote = branch_target
.remote_targets
.iter()
.any(|&(remote, _)| remote != git::REMOTE_NAME_FOR_LOCAL_GIT_REPO);
if found_non_git_remote {
writeln!(
formatter,

View file

@ -359,11 +359,11 @@ impl RefNamesIndex {
fn build_branches_index(repo: &dyn Repo) -> RefNamesIndex {
let mut index = RefNamesIndex::default();
for (branch_name, branch_target) in repo.view().branches() {
let local_target = &branch_target.local_target;
let local_target = branch_target.local_target;
let mut unsynced_remote_targets = branch_target
.remote_targets
.iter()
.filter(|&(_, target)| target != local_target)
.filter(|&&(_, target)| target != local_target)
.peekable();
if local_target.is_present() {
let decorated_name = if local_target.has_conflict() {
@ -375,7 +375,7 @@ fn build_branches_index(repo: &dyn Repo) -> RefNamesIndex {
};
index.insert(local_target.added_ids(), decorated_name);
}
for (remote_name, target) in unsynced_remote_targets {
for &(remote_name, target) in unsynced_remote_targets {
let decorated_name = if target.has_conflict() {
format!("{branch_name}@{remote_name}?")
} else {

View file

@ -166,18 +166,13 @@ impl<'a> RefTargetOptionExt for Option<&'a RefTarget> {
}
}
content_hash! {
#[derive(Default, PartialEq, Eq, Clone, Debug)]
pub struct BranchTarget {
/// The commit the branch points to locally. `None` if the branch has been
/// deleted locally.
pub local_target: RefTarget,
// TODO: Do we need to support tombstones for remote branches? For example, if the branch
// has been deleted locally and you pull from a remote, maybe it should make a difference
// whether the branch is known to have existed on the remote. We may not want to resurrect
// the branch if the branch's state on the remote was just not known.
pub remote_targets: BTreeMap<String, RefTarget>,
}
/// Local and remote branches of the same branch name.
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct BranchTarget<'a> {
/// The commit the branch points to locally.
pub local_target: &'a RefTarget,
/// `(remote_name, target)` pairs in lexicographical order.
pub remote_targets: Vec<(&'a str, &'a RefTarget)>,
}
content_hash! {
@ -208,6 +203,10 @@ content_hash! {
/// Represents the state of the remote repo.
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct RemoteView {
// TODO: Do we need to support tombstones for remote branches? For example, if the branch
// has been deleted locally and you pull from a remote, maybe it should make a difference
// whether the branch is known to have existed on the remote. We may not want to resurrect
// the branch if the branch's state on the remote was just not known.
pub branches: BTreeMap<String, RemoteRef>,
// TODO: pub tags: BTreeMap<String, RemoteRef>,
}
@ -217,7 +216,7 @@ content_hash! {
pub(crate) fn merge_join_branch_views<'a>(
local_branches: &'a BTreeMap<String, RefTarget>,
remote_views: &'a BTreeMap<String, RemoteView>,
) -> impl Iterator<Item = (&'a str, BranchTarget)> {
) -> impl Iterator<Item = (&'a str, BranchTarget<'a>)> {
let mut local_branches_iter = local_branches
.iter()
.map(|(branch_name, target)| (branch_name.as_str(), target))
@ -234,18 +233,14 @@ pub(crate) fn merge_join_branch_views<'a>(
} else {
local_branches_iter.next()?
};
// TODO: add borrowed version of BranchTarget?
let mut branch_target = BranchTarget {
local_target: local_target.clone(),
..Default::default()
let remote_targets = remote_branches_iter
.peeking_take_while(|&((remote_branch_name, _), _)| remote_branch_name == branch_name)
.map(|((_, remote_name), target)| (remote_name, target))
.collect();
let branch_target = BranchTarget {
local_target,
remote_targets,
};
while let Some(((_, remote_name), target)) = remote_branches_iter
.next_if(|&((remote_branch_name, _), _)| remote_branch_name == branch_name)
{
branch_target
.remote_targets
.insert(remote_name.to_owned(), target.clone());
}
Some((branch_name, branch_target))
})
}
@ -381,21 +376,21 @@ mod tests {
(
"branch1",
BranchTarget {
local_target: local_branch1_target.clone(),
remote_targets: btreemap! {
"git".to_owned() => git_branch1_target.clone(),
"remote1".to_owned() => remote1_branch1_target.clone(),
},
local_target: &local_branch1_target,
remote_targets: vec![
("git", &git_branch1_target),
("remote1", &remote1_branch1_target),
],
},
),
(
"branch2",
BranchTarget {
local_target: local_branch2_target.clone(),
remote_targets: btreemap! {
"git".to_owned() => git_branch2_target.clone(),
"remote2".to_owned() => remote2_branch2_target.clone(),
},
local_target: &local_branch2_target,
remote_targets: vec![
("git", &git_branch2_target),
("remote2", &remote2_branch2_target),
],
},
),
],
@ -411,8 +406,8 @@ mod tests {
vec![(
"branch1",
BranchTarget {
local_target: local_branch1_target.clone(),
remote_targets: btreemap! {},
local_target: &local_branch1_target,
remote_targets: vec![],
},
)],
);
@ -431,10 +426,8 @@ mod tests {
vec![(
"branch1",
BranchTarget {
local_target: RefTarget::absent(),
remote_targets: btreemap! {
"remote1".to_owned() => remote1_branch1_target.clone(),
},
local_target: RefTarget::absent_ref(),
remote_targets: vec![("remote1", &remote1_branch1_target)],
},
)],
);

View file

@ -2034,7 +2034,7 @@ fn collect_branch_symbols(repo: &dyn Repo, include_synced_remotes: bool) -> Vec<
let remote_symbols = branch_target
.remote_targets
.into_iter()
.filter(move |(_, target)| include_synced_remotes || *target != local_target)
.filter(move |&(_, target)| include_synced_remotes || target != local_target)
.map(move |(remote_name, _)| format!("{name}@{remote_name}"));
local_symbol.into_iter().chain(remote_symbols)
})

View file

@ -344,14 +344,14 @@ fn branch_views_to_proto_legacy(
) -> Vec<crate::protos::op_store::Branch> {
op_store::merge_join_branch_views(local_branches, remote_views)
.map(|(name, branch_target)| {
let local_target = ref_target_to_proto(&branch_target.local_target);
let local_target = ref_target_to_proto(branch_target.local_target);
let remote_branches = branch_target
.remote_targets
.into_iter()
.iter()
.map(
|(remote_name, target)| crate::protos::op_store::RemoteBranch {
remote_name,
target: ref_target_to_proto(&target),
|&(remote_name, target)| crate::protos::op_store::RemoteBranch {
remote_name: remote_name.to_owned(),
target: ref_target_to_proto(target),
},
)
.collect();

View file

@ -87,7 +87,7 @@ impl View {
}
/// Iterates pair of local and remote branches by branch name.
pub fn branches(&self) -> impl Iterator<Item = (&str, BranchTarget)> {
pub fn branches(&self) -> impl Iterator<Item = (&str, BranchTarget<'_>)> {
op_store::merge_join_branch_views(&self.data.local_branches, &self.data.remote_views)
}

View file

@ -1796,10 +1796,10 @@ fn test_fetch_initial_commit() {
view.branches().collect::<BTreeMap<_, _>>(),
btreemap! {
"main" => BranchTarget {
local_target: initial_commit_target.clone(),
remote_targets: btreemap! {
"origin".to_string() => initial_commit_target,
},
local_target: &initial_commit_target,
remote_targets: vec![
("origin", &initial_commit_target),
],
},
}
);
@ -1867,10 +1867,10 @@ fn test_fetch_success() {
view.branches().collect::<BTreeMap<_, _>>(),
btreemap! {
"main" => BranchTarget {
local_target: new_commit_target.clone(),
remote_targets: btreemap! {
"origin".to_string() => new_commit_target.clone(),
},
local_target: &new_commit_target,
remote_targets: vec![
("origin", &new_commit_target),
],
},
}
);

View file

@ -289,22 +289,25 @@ fn test_merge_views_branches() {
);
let repo = commit_transactions(&settings, vec![tx1, tx2]);
let main_branch_origin_tx1_target = RefTarget::normal(main_branch_origin_tx1.id().clone());
let main_branch_alternate_tx0_target =
RefTarget::normal(main_branch_alternate_tx0.id().clone());
let expected_main_branch = BranchTarget {
local_target: RefTarget::from_legacy_form(
local_target: &RefTarget::from_legacy_form(
[main_branch_local_tx0.id().clone()],
[
main_branch_local_tx1.id().clone(),
main_branch_local_tx2.id().clone(),
],
),
remote_targets: btreemap! {
"origin".to_string() => RefTarget::normal(main_branch_origin_tx1.id().clone()),
"alternate".to_string() => RefTarget::normal(main_branch_alternate_tx0.id().clone()),
},
remote_targets: vec![
("alternate", &main_branch_alternate_tx0_target),
("origin", &main_branch_origin_tx1_target),
],
};
let expected_feature_branch = BranchTarget {
local_target: RefTarget::normal(feature_branch_tx1.id().clone()),
remote_targets: btreemap! {},
local_target: &RefTarget::normal(feature_branch_tx1.id().clone()),
remote_targets: vec![],
};
assert_eq!(
repo.view().branches().collect::<BTreeMap<_, _>>(),