diff --git a/lib/src/merge.rs b/lib/src/merge.rs index 527ce56d7..7721b075d 100644 --- a/lib/src/merge.rs +++ b/lib/src/merge.rs @@ -165,6 +165,16 @@ impl Merge { } } + /// 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> { + 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 diff --git a/lib/src/merged_tree.rs b/lib/src/merged_tree.rs index cd0799f4e..8b41399c1 100644 --- a/lib/src/merged_tree.rs +++ b/lib/src/merged_tree.rs @@ -227,10 +227,13 @@ fn merge_trees(merge: &Merge) -> Result, 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() { diff --git a/lib/src/tree.rs b/lib/src/tree.rs index a02374db7..deeee2d3d 100644 --- a/lib/src/tree.rs +++ b/lib/src/tree.rs @@ -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)) + } + } } } })