mirror of
https://github.com/martinvonz/jj.git
synced 2025-01-05 20:55:05 +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() {
|
||||
return Ok(MergedTree::resolved(tree));
|
||||
}
|
||||
// Find the number of removes in the most complex conflict. We will then
|
||||
// build `2*num_removes + 1` trees
|
||||
let mut max_num_removes = 0;
|
||||
|
||||
// Find the number of removes and adds in the most complex conflict.
|
||||
let mut max_tree_count = 1;
|
||||
let store = tree.store();
|
||||
let mut conflicts: Vec<(&RepoPath, MergedTreeValue)> = vec![];
|
||||
for (path, conflict_id) in &conflict_ids {
|
||||
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));
|
||||
}
|
||||
let mut removes = vec![];
|
||||
let mut adds = vec![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()));
|
||||
}
|
||||
let mut tree_builders = Vec::new();
|
||||
tree_builders.resize_with(max_tree_count, || store.tree_builder(tree.id().clone()));
|
||||
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
|
||||
// add canceling removes and adds of any value. The simplest value is an absent
|
||||
// value, so we use that.
|
||||
for i in num_removes..max_num_removes {
|
||||
removes[i].remove(path.clone());
|
||||
adds[i + 1].remove(path.clone());
|
||||
}
|
||||
// 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 terms_padded = conflict.into_iter().chain(iter::repeat(None));
|
||||
for (builder, term) in zip(&mut tree_builders, terms_padded) {
|
||||
builder.set_or_remove(path.clone(), term);
|
||||
}
|
||||
}
|
||||
|
||||
let write_tree = |builder: TreeBuilder| {
|
||||
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()?;
|
||||
Ok(MergedTree::Merge(Merge::new(removed_trees, added_trees)))
|
||||
let new_trees: Vec<_> = tree_builders
|
||||
.into_iter()
|
||||
.map(|builder| {
|
||||
let tree_id = builder.write_tree();
|
||||
store.get_tree(&RepoPath::root(), &tree_id)
|
||||
})
|
||||
.try_collect()?;
|
||||
Ok(MergedTree::Merge(Merge::from_vec(new_trees)))
|
||||
}
|
||||
|
||||
/// This tree's directory
|
||||
|
|
Loading…
Reference in a new issue