mirror of
https://github.com/martinvonz/jj.git
synced 2025-02-10 06:20:18 +00:00
tree: inline simplify_conflict()
The function is just a few lines now. I don't think we need the long documentation in it either since that's now in docs/technical/conflicts.md.
This commit is contained in:
parent
d4e755b4e4
commit
adf9679d4c
1 changed files with 6 additions and 45 deletions
|
@ -562,14 +562,18 @@ fn merge_tree_value(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// Start by creating a Conflict object. Conflicts can cleanly represent a single
|
// Start by creating a Merge object. Merges can cleanly represent a single
|
||||||
// resolved state, the absence of a state, or a conflicted state.
|
// resolved state, the absence of a state, or a conflicted state.
|
||||||
let conflict = Merge::new(
|
let conflict = Merge::new(
|
||||||
vec![maybe_base.cloned()],
|
vec![maybe_base.cloned()],
|
||||||
vec![maybe_side1.cloned(), maybe_side2.cloned()],
|
vec![maybe_side1.cloned(), maybe_side2.cloned()],
|
||||||
);
|
);
|
||||||
let filename = dir.join(basename);
|
let filename = dir.join(basename);
|
||||||
let merge = simplify_conflict(store, &filename, conflict)?;
|
let expanded = conflict.try_map(|term| match term {
|
||||||
|
Some(TreeValue::Conflict(id)) => store.read_conflict(&filename, id),
|
||||||
|
_ => Ok(Merge::resolved(term.clone())),
|
||||||
|
})?;
|
||||||
|
let merge = expanded.flatten().simplify();
|
||||||
match merge.into_resolved() {
|
match merge.into_resolved() {
|
||||||
Ok(value) => value,
|
Ok(value) => value,
|
||||||
Err(conflict) => {
|
Err(conflict) => {
|
||||||
|
@ -656,46 +660,3 @@ pub fn try_resolve_file_conflict(
|
||||||
MergeResult::Conflict(_) => Ok(None),
|
MergeResult::Conflict(_) => Ok(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn simplify_conflict(
|
|
||||||
store: &Store,
|
|
||||||
path: &RepoPath,
|
|
||||||
conflict: Merge<Option<TreeValue>>,
|
|
||||||
) -> Result<Merge<Option<TreeValue>>, BackendError> {
|
|
||||||
// Important cases to simplify:
|
|
||||||
//
|
|
||||||
// D
|
|
||||||
// |
|
|
||||||
// B C
|
|
||||||
// |/
|
|
||||||
// A
|
|
||||||
//
|
|
||||||
// 1. rebase C to B, then back to A => there should be no conflict
|
|
||||||
// 2. rebase C to B, then to D => the conflict should not mention B
|
|
||||||
// 3. rebase B to C and D to B', then resolve the conflict in B' and rebase D'
|
|
||||||
// on top => the conflict should be between B'', B, and D; it should not
|
|
||||||
// mention the conflict in B'
|
|
||||||
|
|
||||||
// Case 1 above:
|
|
||||||
// After first rebase, the conflict is {+B-A+C}. After rebasing back,
|
|
||||||
// the unsimplified conflict is {+A-B+{+B-A+C}}. Since the
|
|
||||||
// inner conflict is positive, we can simply move it into the outer conflict. We
|
|
||||||
// thus get {+A-B+B-A+C}, which we can then simplify to just C (because {+C} ==
|
|
||||||
// C).
|
|
||||||
//
|
|
||||||
// Case 2 above:
|
|
||||||
// After first rebase, the conflict is {+B-A+C}. After rebasing to D,
|
|
||||||
// the unsimplified conflict is {+D-C+{+B-A+C}}. As in the
|
|
||||||
// previous case, the inner conflict can be moved into the outer one. We then
|
|
||||||
// get {+D-C+B-A+C}. That can be simplified to
|
|
||||||
// {+D+B-A}, which is the desired conflict.
|
|
||||||
//
|
|
||||||
// Case 3 above:
|
|
||||||
// TODO: describe this case
|
|
||||||
|
|
||||||
let expanded = conflict.try_map(|term| match term {
|
|
||||||
Some(TreeValue::Conflict(id)) => store.read_conflict(path, id),
|
|
||||||
_ => Ok(Merge::resolved(term.clone())),
|
|
||||||
})?;
|
|
||||||
Ok(expanded.flatten().simplify())
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue