FA-75821 / Text diff and three-way merge / Open access
Conflict resolution reuse: unmatched conflicts disappear · case 01
Conflicts with no recorded resolution vanish from the file along with both sides.
ROOT CAUSE
The unmatched branch counts the conflict but writes nothing.
VERIFIED REPAIR
Re-emit unmatched conflicts with markers so they can still be resolved.
Unsuccessful approach: Writing only our side silently resolves the conflict in our favour.
Case contract
Scan conflict blocks ("<<<<<<<" optionally followed by a label, optional "|||||||" base section, "=======", ">>>>>>>" optionally labelled). A block matches a recorded [side1, side2, resolution] when its two sides equal the recorded sides in either order; base lines are ignored. Matched blocks are replaced by the resolution; unmatched blocks are re-emitted as bare "<<<<<<<", ours, "=======", theirs, ">>>>>>>" and counted. Return lines and the unresolved count.
Why this case matters
Reusing recorded conflict resolutions saves repeating the same manual merge during rebases.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(lines, recorded):
out = []
state = None
o, t = [], []
unresolved = 0
for ln in lines:
if state is None:
if ln.startswith('<<<<<<<'):
state = 'o'
o, t = [], []
else:
out.append(ln)
elif state == 'o' and ln.startswith('|||||||'):
state = 'b'
elif state in ('o', 'b') and ln == '=======':
state = 't'
elif state == 't' and ln.startswith('>>>>>>>'):
key = sorted([o, t])
match = next((r[2] for r in recorded if sorted([r[0], r[1]]) == key), None)
if match is not None:
out.extend(match)
else:
unresolved += 1
pass
state = None
elif state == 'o':
o.append(ln)
elif state == 't':
t.append(ln)
return {'lines': out, 'unresolved': unresolved}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = {
1: [('recorded resolution reused', [['pre', '<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'post'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0}), ('sides swapped still match', [['<<<<<<< HEAD', 'x = 2', '=======', 'x = 1', '>>>>>>> topic1'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0}), ('base section does not affect the fingerprint', [['<<<<<<< ours', 'c', '||||||| base', 'orig', '=======', 'a', 'b', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('unknown conflict stays unresolved', [['<<<<<<< ours', 'p1', '=======', 'q', '>>>>>>> theirs', 'tail'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['<<<<<<<', 'p1', '=======', 'q', '>>>>>>>', 'tail'], 'unresolved': 1}), ('unlabelled markers', [['<<<<<<<', 'a', 'b', '=======', 'c', '>>>>>>>'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('two conflicts, one known', [['<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'mid', '<<<<<<< ours', 'm', '=======', 'n', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3', 'mid', '<<<<<<<', 'm', '=======', 'n', '>>>>>>>'], 'unresolved': 1}), ('labelled base marker', [['<<<<<<< ours', 'x = 2', '||||||| base', 'x = 0', '=======', 'x = 1', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0})],
2: [('recorded resolution reused', [['pre', '<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'post'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0}), ('sides swapped still match', [['<<<<<<< HEAD', 'x = 2', '=======', 'x = 1', '>>>>>>> topic2'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0}), ('base section does not affect the fingerprint', [['<<<<<<< ours', 'c', '||||||| base', 'orig', '=======', 'a', 'b', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('unknown conflict stays unresolved', [['<<<<<<< ours', 'p2', '=======', 'q', '>>>>>>> theirs', 'tail'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['<<<<<<<', 'p2', '=======', 'q', '>>>>>>>', 'tail'], 'unresolved': 1}), ('unlabelled markers', [['<<<<<<<', 'a', 'b', '=======', 'c', '>>>>>>>'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('two conflicts, one known', [['<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'mid', '<<<<<<< ours', 'm', '=======', 'n', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3', 'mid', '<<<<<<<', 'm', '=======', 'n', '>>>>>>>'], 'unresolved': 1}), ('labelled base marker', [['<<<<<<< ours', 'x = 2', '||||||| base', 'x = 0', '=======', 'x = 1', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0})],
3: [('recorded resolution reused', [['pre', '<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'post'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0}), ('sides swapped still match', [['<<<<<<< HEAD', 'x = 2', '=======', 'x = 1', '>>>>>>> topic3'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0}), ('base section does not affect the fingerprint', [['<<<<<<< ours', 'c', '||||||| base', 'orig', '=======', 'a', 'b', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('unknown conflict stays unresolved', [['<<<<<<< ours', 'p3', '=======', 'q', '>>>>>>> theirs', 'tail'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['<<<<<<<', 'p3', '=======', 'q', '>>>>>>>', 'tail'], 'unresolved': 1}), ('unlabelled markers', [['<<<<<<<', 'a', 'b', '=======', 'c', '>>>>>>>'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('two conflicts, one known', [['<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'mid', '<<<<<<< ours', 'm', '=======', 'n', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3', 'mid', '<<<<<<<', 'm', '=======', 'n', '>>>>>>>'], 'unresolved': 1}), ('labelled base marker', [['<<<<<<< ours', 'x = 2', '||||||| base', 'x = 0', '=======', 'x = 1', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0})],
4: [('recorded resolution reused', [['pre', '<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'post'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0}), ('sides swapped still match', [['<<<<<<< HEAD', 'x = 2', '=======', 'x = 1', '>>>>>>> topic4'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0}), ('base section does not affect the fingerprint', [['<<<<<<< ours', 'c', '||||||| base', 'orig', '=======', 'a', 'b', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('unknown conflict stays unresolved', [['<<<<<<< ours', 'p4', '=======', 'q', '>>>>>>> theirs', 'tail'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['<<<<<<<', 'p4', '=======', 'q', '>>>>>>>', 'tail'], 'unresolved': 1}), ('unlabelled markers', [['<<<<<<<', 'a', 'b', '=======', 'c', '>>>>>>>'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('two conflicts, one known', [['<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'mid', '<<<<<<< ours', 'm', '=======', 'n', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3', 'mid', '<<<<<<<', 'm', '=======', 'n', '>>>>>>>'], 'unresolved': 1}), ('labelled base marker', [['<<<<<<< ours', 'x = 2', '||||||| base', 'x = 0', '=======', 'x = 1', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0})],
5: [('recorded resolution reused', [['pre', '<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'post'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0}), ('sides swapped still match', [['<<<<<<< HEAD', 'x = 2', '=======', 'x = 1', '>>>>>>> topic5'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0}), ('base section does not affect the fingerprint', [['<<<<<<< ours', 'c', '||||||| base', 'orig', '=======', 'a', 'b', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('unknown conflict stays unresolved', [['<<<<<<< ours', 'p5', '=======', 'q', '>>>>>>> theirs', 'tail'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['<<<<<<<', 'p5', '=======', 'q', '>>>>>>>', 'tail'], 'unresolved': 1}), ('unlabelled markers', [['<<<<<<<', 'a', 'b', '=======', 'c', '>>>>>>>'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('two conflicts, one known', [['<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'mid', '<<<<<<< ours', 'm', '=======', 'n', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3', 'mid', '<<<<<<<', 'm', '=======', 'n', '>>>>>>>'], 'unresolved': 1}), ('labelled base marker', [['<<<<<<< ours', 'x = 2', '||||||| base', 'x = 0', '=======', 'x = 1', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0})],
}[N]
for label, args, expected in cases:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| recorded resolution reused | {'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0} | {'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0} | Passed |
| sides swapped still match | {'lines': ['x = 3'], 'unresolved': 0} | {'lines': ['x = 3'], 'unresolved': 0} | Passed |
| base section does not affect the fingerprint | {'lines': ['abc'], 'unresolved': 0} | {'lines': ['abc'], 'unresolved': 0} | Passed |
| unknown conflict stays unresolved | {'lines': ['tail'], 'unresolved': 1} | {'lines': ['<<<<<<<', 'p1', '=======', 'q', '>>>>>>>', 'tail'], 'unresolved': 1} | Failed |
| unlabelled markers | {'lines': ['abc'], 'unresolved': 0} | {'lines': ['abc'], 'unresolved': 0} | Passed |
| two conflicts, one known | {'lines': ['x = 3', 'mid'], 'unresolved': 1} | {'lines': ['x = 3', 'mid', '<<<<<<<', 'm', '=======', 'n', '>>>>>>>'], 'unresolved': 1} | Failed |
| labelled base marker | {'lines': ['x = 3'], 'unresolved': 0} | {'lines': ['x = 3'], 'unresolved': 0} | Passed |
SHA-256 / 79594cded76dd0e9c03dc069fe01a42633e74ab846f12b07991b715a174ba8aa
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(lines, recorded):
out = []
state = None
o, t = [], []
unresolved = 0
for ln in lines:
if state is None:
if ln.startswith('<<<<<<<'):
state = 'o'
o, t = [], []
else:
out.append(ln)
elif state == 'o' and ln.startswith('|||||||'):
state = 'b'
elif state in ('o', 'b') and ln == '=======':
state = 't'
elif state == 't' and ln.startswith('>>>>>>>'):
key = sorted([o, t])
match = next((r[2] for r in recorded if sorted([r[0], r[1]]) == key), None)
if match is not None:
out.extend(match)
else:
unresolved += 1
out.extend(o)
state = None
elif state == 'o':
o.append(ln)
elif state == 't':
t.append(ln)
return {'lines': out, 'unresolved': unresolved}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = {
1: [('recorded resolution reused', [['pre', '<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'post'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0}), ('sides swapped still match', [['<<<<<<< HEAD', 'x = 2', '=======', 'x = 1', '>>>>>>> topic1'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0}), ('base section does not affect the fingerprint', [['<<<<<<< ours', 'c', '||||||| base', 'orig', '=======', 'a', 'b', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('unknown conflict stays unresolved', [['<<<<<<< ours', 'p1', '=======', 'q', '>>>>>>> theirs', 'tail'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['<<<<<<<', 'p1', '=======', 'q', '>>>>>>>', 'tail'], 'unresolved': 1}), ('unlabelled markers', [['<<<<<<<', 'a', 'b', '=======', 'c', '>>>>>>>'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('two conflicts, one known', [['<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'mid', '<<<<<<< ours', 'm', '=======', 'n', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3', 'mid', '<<<<<<<', 'm', '=======', 'n', '>>>>>>>'], 'unresolved': 1}), ('labelled base marker', [['<<<<<<< ours', 'x = 2', '||||||| base', 'x = 0', '=======', 'x = 1', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0})],
2: [('recorded resolution reused', [['pre', '<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'post'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0}), ('sides swapped still match', [['<<<<<<< HEAD', 'x = 2', '=======', 'x = 1', '>>>>>>> topic2'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0}), ('base section does not affect the fingerprint', [['<<<<<<< ours', 'c', '||||||| base', 'orig', '=======', 'a', 'b', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('unknown conflict stays unresolved', [['<<<<<<< ours', 'p2', '=======', 'q', '>>>>>>> theirs', 'tail'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['<<<<<<<', 'p2', '=======', 'q', '>>>>>>>', 'tail'], 'unresolved': 1}), ('unlabelled markers', [['<<<<<<<', 'a', 'b', '=======', 'c', '>>>>>>>'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('two conflicts, one known', [['<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'mid', '<<<<<<< ours', 'm', '=======', 'n', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3', 'mid', '<<<<<<<', 'm', '=======', 'n', '>>>>>>>'], 'unresolved': 1}), ('labelled base marker', [['<<<<<<< ours', 'x = 2', '||||||| base', 'x = 0', '=======', 'x = 1', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0})],
3: [('recorded resolution reused', [['pre', '<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'post'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0}), ('sides swapped still match', [['<<<<<<< HEAD', 'x = 2', '=======', 'x = 1', '>>>>>>> topic3'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0}), ('base section does not affect the fingerprint', [['<<<<<<< ours', 'c', '||||||| base', 'orig', '=======', 'a', 'b', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('unknown conflict stays unresolved', [['<<<<<<< ours', 'p3', '=======', 'q', '>>>>>>> theirs', 'tail'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['<<<<<<<', 'p3', '=======', 'q', '>>>>>>>', 'tail'], 'unresolved': 1}), ('unlabelled markers', [['<<<<<<<', 'a', 'b', '=======', 'c', '>>>>>>>'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('two conflicts, one known', [['<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'mid', '<<<<<<< ours', 'm', '=======', 'n', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3', 'mid', '<<<<<<<', 'm', '=======', 'n', '>>>>>>>'], 'unresolved': 1}), ('labelled base marker', [['<<<<<<< ours', 'x = 2', '||||||| base', 'x = 0', '=======', 'x = 1', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0})],
4: [('recorded resolution reused', [['pre', '<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'post'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0}), ('sides swapped still match', [['<<<<<<< HEAD', 'x = 2', '=======', 'x = 1', '>>>>>>> topic4'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0}), ('base section does not affect the fingerprint', [['<<<<<<< ours', 'c', '||||||| base', 'orig', '=======', 'a', 'b', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('unknown conflict stays unresolved', [['<<<<<<< ours', 'p4', '=======', 'q', '>>>>>>> theirs', 'tail'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['<<<<<<<', 'p4', '=======', 'q', '>>>>>>>', 'tail'], 'unresolved': 1}), ('unlabelled markers', [['<<<<<<<', 'a', 'b', '=======', 'c', '>>>>>>>'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('two conflicts, one known', [['<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'mid', '<<<<<<< ours', 'm', '=======', 'n', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3', 'mid', '<<<<<<<', 'm', '=======', 'n', '>>>>>>>'], 'unresolved': 1}), ('labelled base marker', [['<<<<<<< ours', 'x = 2', '||||||| base', 'x = 0', '=======', 'x = 1', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0})],
5: [('recorded resolution reused', [['pre', '<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'post'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0}), ('sides swapped still match', [['<<<<<<< HEAD', 'x = 2', '=======', 'x = 1', '>>>>>>> topic5'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0}), ('base section does not affect the fingerprint', [['<<<<<<< ours', 'c', '||||||| base', 'orig', '=======', 'a', 'b', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('unknown conflict stays unresolved', [['<<<<<<< ours', 'p5', '=======', 'q', '>>>>>>> theirs', 'tail'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['<<<<<<<', 'p5', '=======', 'q', '>>>>>>>', 'tail'], 'unresolved': 1}), ('unlabelled markers', [['<<<<<<<', 'a', 'b', '=======', 'c', '>>>>>>>'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('two conflicts, one known', [['<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'mid', '<<<<<<< ours', 'm', '=======', 'n', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3', 'mid', '<<<<<<<', 'm', '=======', 'n', '>>>>>>>'], 'unresolved': 1}), ('labelled base marker', [['<<<<<<< ours', 'x = 2', '||||||| base', 'x = 0', '=======', 'x = 1', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0})],
}[N]
for label, args, expected in cases:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| recorded resolution reused | {'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0} | {'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0} | Passed |
| sides swapped still match | {'lines': ['x = 3'], 'unresolved': 0} | {'lines': ['x = 3'], 'unresolved': 0} | Passed |
| base section does not affect the fingerprint | {'lines': ['abc'], 'unresolved': 0} | {'lines': ['abc'], 'unresolved': 0} | Passed |
| unknown conflict stays unresolved | {'lines': ['p1', 'tail'], 'unresolved': 1} | {'lines': ['<<<<<<<', 'p1', '=======', 'q', '>>>>>>>', 'tail'], 'unresolved': 1} | Failed |
| unlabelled markers | {'lines': ['abc'], 'unresolved': 0} | {'lines': ['abc'], 'unresolved': 0} | Passed |
| two conflicts, one known | {'lines': ['x = 3', 'mid', 'm'], 'unresolved': 1} | {'lines': ['x = 3', 'mid', '<<<<<<<', 'm', '=======', 'n', '>>>>>>>'], 'unresolved': 1} | Failed |
| labelled base marker | {'lines': ['x = 3'], 'unresolved': 0} | {'lines': ['x = 3'], 'unresolved': 0} | Passed |
SHA-256 / 87546a5f3ea5ad0db46e7bef88d9548fcef4d7959388aa235ae838fc1001e40a
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(lines, recorded):
out = []
state = None
o, t = [], []
unresolved = 0
for ln in lines:
if state is None:
if ln.startswith('<<<<<<<'):
state = 'o'
o, t = [], []
else:
out.append(ln)
elif state == 'o' and ln.startswith('|||||||'):
state = 'b'
elif state in ('o', 'b') and ln == '=======':
state = 't'
elif state == 't' and ln.startswith('>>>>>>>'):
key = sorted([o, t])
match = next((r[2] for r in recorded if sorted([r[0], r[1]]) == key), None)
if match is not None:
out.extend(match)
else:
unresolved += 1
out.extend(['<<<<<<<'] + o + ['======='] + t + ['>>>>>>>'])
state = None
elif state == 'o':
o.append(ln)
elif state == 't':
t.append(ln)
return {'lines': out, 'unresolved': unresolved}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = {
1: [('recorded resolution reused', [['pre', '<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'post'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0}), ('sides swapped still match', [['<<<<<<< HEAD', 'x = 2', '=======', 'x = 1', '>>>>>>> topic1'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0}), ('base section does not affect the fingerprint', [['<<<<<<< ours', 'c', '||||||| base', 'orig', '=======', 'a', 'b', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('unknown conflict stays unresolved', [['<<<<<<< ours', 'p1', '=======', 'q', '>>>>>>> theirs', 'tail'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['<<<<<<<', 'p1', '=======', 'q', '>>>>>>>', 'tail'], 'unresolved': 1}), ('unlabelled markers', [['<<<<<<<', 'a', 'b', '=======', 'c', '>>>>>>>'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('two conflicts, one known', [['<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'mid', '<<<<<<< ours', 'm', '=======', 'n', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3', 'mid', '<<<<<<<', 'm', '=======', 'n', '>>>>>>>'], 'unresolved': 1}), ('labelled base marker', [['<<<<<<< ours', 'x = 2', '||||||| base', 'x = 0', '=======', 'x = 1', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0})],
2: [('recorded resolution reused', [['pre', '<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'post'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0}), ('sides swapped still match', [['<<<<<<< HEAD', 'x = 2', '=======', 'x = 1', '>>>>>>> topic2'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0}), ('base section does not affect the fingerprint', [['<<<<<<< ours', 'c', '||||||| base', 'orig', '=======', 'a', 'b', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('unknown conflict stays unresolved', [['<<<<<<< ours', 'p2', '=======', 'q', '>>>>>>> theirs', 'tail'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['<<<<<<<', 'p2', '=======', 'q', '>>>>>>>', 'tail'], 'unresolved': 1}), ('unlabelled markers', [['<<<<<<<', 'a', 'b', '=======', 'c', '>>>>>>>'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('two conflicts, one known', [['<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'mid', '<<<<<<< ours', 'm', '=======', 'n', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3', 'mid', '<<<<<<<', 'm', '=======', 'n', '>>>>>>>'], 'unresolved': 1}), ('labelled base marker', [['<<<<<<< ours', 'x = 2', '||||||| base', 'x = 0', '=======', 'x = 1', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0})],
3: [('recorded resolution reused', [['pre', '<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'post'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0}), ('sides swapped still match', [['<<<<<<< HEAD', 'x = 2', '=======', 'x = 1', '>>>>>>> topic3'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0}), ('base section does not affect the fingerprint', [['<<<<<<< ours', 'c', '||||||| base', 'orig', '=======', 'a', 'b', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('unknown conflict stays unresolved', [['<<<<<<< ours', 'p3', '=======', 'q', '>>>>>>> theirs', 'tail'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['<<<<<<<', 'p3', '=======', 'q', '>>>>>>>', 'tail'], 'unresolved': 1}), ('unlabelled markers', [['<<<<<<<', 'a', 'b', '=======', 'c', '>>>>>>>'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('two conflicts, one known', [['<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'mid', '<<<<<<< ours', 'm', '=======', 'n', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3', 'mid', '<<<<<<<', 'm', '=======', 'n', '>>>>>>>'], 'unresolved': 1}), ('labelled base marker', [['<<<<<<< ours', 'x = 2', '||||||| base', 'x = 0', '=======', 'x = 1', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0})],
4: [('recorded resolution reused', [['pre', '<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'post'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0}), ('sides swapped still match', [['<<<<<<< HEAD', 'x = 2', '=======', 'x = 1', '>>>>>>> topic4'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0}), ('base section does not affect the fingerprint', [['<<<<<<< ours', 'c', '||||||| base', 'orig', '=======', 'a', 'b', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('unknown conflict stays unresolved', [['<<<<<<< ours', 'p4', '=======', 'q', '>>>>>>> theirs', 'tail'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['<<<<<<<', 'p4', '=======', 'q', '>>>>>>>', 'tail'], 'unresolved': 1}), ('unlabelled markers', [['<<<<<<<', 'a', 'b', '=======', 'c', '>>>>>>>'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('two conflicts, one known', [['<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'mid', '<<<<<<< ours', 'm', '=======', 'n', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3', 'mid', '<<<<<<<', 'm', '=======', 'n', '>>>>>>>'], 'unresolved': 1}), ('labelled base marker', [['<<<<<<< ours', 'x = 2', '||||||| base', 'x = 0', '=======', 'x = 1', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0})],
5: [('recorded resolution reused', [['pre', '<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'post'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0}), ('sides swapped still match', [['<<<<<<< HEAD', 'x = 2', '=======', 'x = 1', '>>>>>>> topic5'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0}), ('base section does not affect the fingerprint', [['<<<<<<< ours', 'c', '||||||| base', 'orig', '=======', 'a', 'b', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('unknown conflict stays unresolved', [['<<<<<<< ours', 'p5', '=======', 'q', '>>>>>>> theirs', 'tail'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['<<<<<<<', 'p5', '=======', 'q', '>>>>>>>', 'tail'], 'unresolved': 1}), ('unlabelled markers', [['<<<<<<<', 'a', 'b', '=======', 'c', '>>>>>>>'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['abc'], 'unresolved': 0}), ('two conflicts, one known', [['<<<<<<< ours', 'x = 1', '=======', 'x = 2', '>>>>>>> theirs', 'mid', '<<<<<<< ours', 'm', '=======', 'n', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3', 'mid', '<<<<<<<', 'm', '=======', 'n', '>>>>>>>'], 'unresolved': 1}), ('labelled base marker', [['<<<<<<< ours', 'x = 2', '||||||| base', 'x = 0', '=======', 'x = 1', '>>>>>>> theirs'], [[['x = 1'], ['x = 2'], ['x = 3']], [['a', 'b'], ['c'], ['abc']]]], {'lines': ['x = 3'], 'unresolved': 0})],
}[N]
for label, args, expected in cases:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| recorded resolution reused | {'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0} | {'lines': ['pre', 'x = 3', 'post'], 'unresolved': 0} | Passed |
| sides swapped still match | {'lines': ['x = 3'], 'unresolved': 0} | {'lines': ['x = 3'], 'unresolved': 0} | Passed |
| base section does not affect the fingerprint | {'lines': ['abc'], 'unresolved': 0} | {'lines': ['abc'], 'unresolved': 0} | Passed |
| unknown conflict stays unresolved | {'lines': ['<<<<<<<', 'p1', '=======', 'q', '>>>>>>>', 'tail'], 'unresolved': 1} | {'lines': ['<<<<<<<', 'p1', '=======', 'q', '>>>>>>>', 'tail'], 'unresolved': 1} | Passed |
| unlabelled markers | {'lines': ['abc'], 'unresolved': 0} | {'lines': ['abc'], 'unresolved': 0} | Passed |
| two conflicts, one known | {'lines': ['x = 3', 'mid', '<<<<<<<', 'm', '=======', 'n', '>>>>>>>'], 'unresolved': 1} | {'lines': ['x = 3', 'mid', '<<<<<<<', 'm', '=======', 'n', '>>>>>>>'], 'unresolved': 1} | Passed |
| labelled base marker | {'lines': ['x = 3'], 'unresolved': 0} | {'lines': ['x = 3'], 'unresolved': 0} | Passed |
SHA-256 / 06206ed748ff46cbd75b15c89385569ab4ecfe0d9baba751ff01bfa02a567964
Verification & scope
A deterministic, bounded teaching model of one diff, patch or merge rule with stipulated conventions; it is not a production diff or version-control implementation and makes no claim of conformance to any specific tool. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.
Observations recorded using Python 3.12.14 at 2026-09-29T14:49:10.354162+00:00.
Case digest / 5d615ba00a2cfe002c120cfec36f67b4c110d3810f72817ccdf0d4466d663aab