mirror of
https://github.com/martinvonz/jj.git
synced 2025-01-07 05:16:33 +00:00
merged_tree: convert from legacy conflicts through interleaved list
This is basically the same change as the previous commit.
This commit is contained in:
parent
a734f46130
commit
2c128f1b61
1 changed files with 17 additions and 29 deletions
|
@ -107,48 +107,36 @@ impl MergedTree {
|
||||||
if conflict_ids.is_empty() {
|
if conflict_ids.is_empty() {
|
||||||
return Ok(MergedTree::resolved(tree));
|
return Ok(MergedTree::resolved(tree));
|
||||||
}
|
}
|
||||||
// Find the number of removes in the most complex conflict. We will then
|
|
||||||
// build `2*num_removes + 1` trees
|
// Find the number of removes and adds in the most complex conflict.
|
||||||
let mut max_num_removes = 0;
|
let mut max_tree_count = 1;
|
||||||
let store = tree.store();
|
let store = tree.store();
|
||||||
let mut conflicts: Vec<(&RepoPath, MergedTreeValue)> = vec![];
|
let mut conflicts: Vec<(&RepoPath, MergedTreeValue)> = vec![];
|
||||||
for (path, conflict_id) in &conflict_ids {
|
for (path, conflict_id) in &conflict_ids {
|
||||||
let conflict = store.read_conflict(path, conflict_id)?;
|
let conflict = store.read_conflict(path, conflict_id)?;
|
||||||
max_num_removes = max(max_num_removes, conflict.removes().len());
|
max_tree_count = max(max_tree_count, conflict.iter().len());
|
||||||
conflicts.push((path, conflict));
|
conflicts.push((path, conflict));
|
||||||
}
|
}
|
||||||
let mut removes = vec![];
|
let mut tree_builders = Vec::new();
|
||||||
let mut adds = vec![store.tree_builder(tree.id().clone())];
|
tree_builders.resize_with(max_tree_count, || store.tree_builder(tree.id().clone()));
|
||||||
for _ in 0..max_num_removes {
|
|
||||||
removes.push(store.tree_builder(tree.id().clone()));
|
|
||||||
adds.push(store.tree_builder(tree.id().clone()));
|
|
||||||
}
|
|
||||||
for (path, conflict) in conflicts {
|
for (path, conflict) in conflicts {
|
||||||
let num_removes = conflict.removes().len();
|
|
||||||
// If there are fewer terms in this conflict than in some other conflict, we can
|
// If there are fewer terms in this conflict than in some other conflict, we can
|
||||||
// add canceling removes and adds of any value. The simplest value is an absent
|
// add canceling removes and adds of any value. The simplest value is an absent
|
||||||
// value, so we use that.
|
// value, so we use that.
|
||||||
for i in num_removes..max_num_removes {
|
let terms_padded = conflict.into_iter().chain(iter::repeat(None));
|
||||||
removes[i].remove(path.clone());
|
for (builder, term) in zip(&mut tree_builders, terms_padded) {
|
||||||
adds[i + 1].remove(path.clone());
|
builder.set_or_remove(path.clone(), term);
|
||||||
}
|
|
||||||
// Now add the terms that were present in the conflict to the appropriate trees.
|
|
||||||
for (i, term) in conflict.removes().enumerate() {
|
|
||||||
removes[i].set_or_remove(path.clone(), term.clone());
|
|
||||||
}
|
|
||||||
for (i, term) in conflict.adds().enumerate() {
|
|
||||||
adds[i].set_or_remove(path.clone(), term.clone());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let write_tree = |builder: TreeBuilder| {
|
let new_trees: Vec<_> = tree_builders
|
||||||
let tree_id = builder.write_tree();
|
.into_iter()
|
||||||
store.get_tree(&RepoPath::root(), &tree_id)
|
.map(|builder| {
|
||||||
};
|
let tree_id = builder.write_tree();
|
||||||
|
store.get_tree(&RepoPath::root(), &tree_id)
|
||||||
let removed_trees = removes.into_iter().map(write_tree).try_collect()?;
|
})
|
||||||
let added_trees = adds.into_iter().map(write_tree).try_collect()?;
|
.try_collect()?;
|
||||||
Ok(MergedTree::Merge(Merge::new(removed_trees, added_trees)))
|
Ok(MergedTree::Merge(Merge::from_vec(new_trees)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This tree's directory
|
/// This tree's directory
|
||||||
|
|
Loading…
Reference in a new issue