mirror of
https://github.com/martinvonz/jj.git
synced 2025-01-18 18:27:38 +00:00
merge: add a Merge::into_resolved()
to avoid cloning
I don't know if this has any measurable impact. It just seems like we should be able to take a resolved value out of a `Merge` without clonning.
This commit is contained in:
parent
f7160cf936
commit
0570963fe3
3 changed files with 29 additions and 12 deletions
|
@ -165,6 +165,16 @@ impl<T> Merge<T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the resolved value, if this merge is resolved. Otherwise returns
|
||||
/// the merge itself as an `Err`. Does not resolve trivial merges.
|
||||
pub fn into_resolved(mut self) -> Result<T, Merge<T>> {
|
||||
if self.removes.is_empty() {
|
||||
Ok(self.adds.pop().unwrap())
|
||||
} else {
|
||||
Err(self)
|
||||
}
|
||||
}
|
||||
|
||||
/// Simplify the merge by joining diffs like A->B and B->C into A->C.
|
||||
/// Also drops trivial diffs like A->A.
|
||||
pub fn simplify(mut self) -> Self
|
||||
|
|
|
@ -227,10 +227,13 @@ fn merge_trees(merge: &Merge<Tree>) -> Result<Merge<Tree>, TreeMergeError> {
|
|||
for basename in all_tree_conflict_names(merge) {
|
||||
let path_merge = merge.map(|tree| tree.value(basename).cloned());
|
||||
let path_merge = merge_tree_values(store, dir, path_merge)?;
|
||||
if let Some(value) = path_merge.as_resolved() {
|
||||
new_tree.set_or_remove(basename, value.clone());
|
||||
} else {
|
||||
conflicts.push((basename, path_merge));
|
||||
match path_merge.into_resolved() {
|
||||
Ok(value) => {
|
||||
new_tree.set_or_remove(basename, value);
|
||||
}
|
||||
Err(path_merge) => {
|
||||
conflicts.push((basename, path_merge));
|
||||
}
|
||||
};
|
||||
}
|
||||
if conflicts.is_empty() {
|
||||
|
|
|
@ -570,14 +570,18 @@ fn merge_tree_value(
|
|||
);
|
||||
let filename = dir.join(basename);
|
||||
let merge = simplify_conflict(store, &filename, conflict)?;
|
||||
if let Some(value) = merge.as_resolved() {
|
||||
return Ok(value.clone());
|
||||
}
|
||||
if let Some(tree_value) = try_resolve_file_conflict(store, &filename, &merge)? {
|
||||
Some(tree_value)
|
||||
} else {
|
||||
let conflict_id = store.write_conflict(&filename, &merge)?;
|
||||
Some(TreeValue::Conflict(conflict_id))
|
||||
match merge.into_resolved() {
|
||||
Ok(value) => value,
|
||||
Err(conflict) => {
|
||||
if let Some(tree_value) =
|
||||
try_resolve_file_conflict(store, &filename, &conflict)?
|
||||
{
|
||||
Some(tree_value)
|
||||
} else {
|
||||
let conflict_id = store.write_conflict(&filename, &conflict)?;
|
||||
Some(TreeValue::Conflict(conflict_id))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue