forked from mirrors/jj
refs: retry trivial resolution after merging targets
This helps resolve diverged refs by abandoning both sides: D ref = [D] |\ | C C ref = [B - D + C] | | | B | B | B ref = [B - D + A] |/ |/ | A A A A ref = [A - D + A]
This commit is contained in:
parent
982ee63ba8
commit
11b9888cdf
2 changed files with 38 additions and 2 deletions
|
@ -102,10 +102,16 @@ pub fn merge_ref_targets(
|
||||||
])
|
])
|
||||||
.flatten()
|
.flatten()
|
||||||
.simplify();
|
.simplify();
|
||||||
if !merge.is_resolved() {
|
// Suppose left = [A - C + B], base = [B], right = [A], the merge result is
|
||||||
|
// [A - C + A], which can now be trivially resolved.
|
||||||
|
if let Some(resolved) = merge.resolve_trivial() {
|
||||||
|
RefTarget::resolved(resolved.clone())
|
||||||
|
} else {
|
||||||
merge_ref_targets_non_trivial(index, &mut merge);
|
merge_ref_targets_non_trivial(index, &mut merge);
|
||||||
|
// TODO: Maybe better to try resolve_trivial() again, but the result is
|
||||||
|
// unreliable since merge_ref_targets_non_trivial() is order dependent.
|
||||||
|
RefTarget::from_merge(merge)
|
||||||
}
|
}
|
||||||
RefTarget::from_merge(merge)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn merge_remote_refs(
|
pub fn merge_remote_refs(
|
||||||
|
|
|
@ -363,6 +363,36 @@ fn test_merge_ref_targets() {
|
||||||
target4
|
target4
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Existing conflict on left, right moves one side of conflict to the other
|
||||||
|
// side ("A - B + A" - type conflict)
|
||||||
|
assert_eq!(
|
||||||
|
merge_ref_targets(
|
||||||
|
index,
|
||||||
|
&RefTarget::from_legacy_form(
|
||||||
|
[commit5.id().clone()], // not an ancestor of commit3, 4
|
||||||
|
[commit3.id().clone(), commit4.id().clone()],
|
||||||
|
),
|
||||||
|
&target4,
|
||||||
|
&target3,
|
||||||
|
),
|
||||||
|
target3
|
||||||
|
);
|
||||||
|
|
||||||
|
// Existing conflict on right, left moves one side of conflict to the other
|
||||||
|
// side ("A - B + A" - type conflict)
|
||||||
|
assert_eq!(
|
||||||
|
merge_ref_targets(
|
||||||
|
index,
|
||||||
|
&target4,
|
||||||
|
&target3,
|
||||||
|
&RefTarget::from_legacy_form(
|
||||||
|
[commit5.id().clone()], // not an ancestor of commit3, 4
|
||||||
|
[commit3.id().clone(), commit4.id().clone()],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
target4
|
||||||
|
);
|
||||||
|
|
||||||
// Existing conflict on left, right makes unrelated update
|
// Existing conflict on left, right makes unrelated update
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
merge_ref_targets(
|
merge_ref_targets(
|
||||||
|
|
Loading…
Reference in a new issue