render_markers() now always renders minimized 2-way markers, so
let's simplify and rename it accordingly.
Details
Details
Diff Detail
Diff Detail
- Repository
- rHG Mercurial
- Branch
- default
- Lint
No Linters Available - Unit
No Unit Test Coverage
( )
render_markers() now always renders minimized 2-way markers, so
let's simplify and rename it accordingly.
No Linters Available |
No Unit Test Coverage |
Path | Packages | |||
---|---|---|---|---|
M | mercurial/debugcommands.py (3 lines) | |||
M | mercurial/simplemerge.py (26 lines) | |||
M | tests/test-simplemerge.py (20 lines) |
Commit | Parents | Author | Summary | Date |
---|---|---|---|---|
ba52da80f3e6 | cf82747a8878 | Martin von Zweigbergk | Jan 12 2022, 12:56 AM |
Status | Author | Revision | |
---|---|---|---|
Closed | martinvonz | ||
Closed | martinvonz | ||
Closed | martinvonz | ||
Closed | martinvonz | ||
Closed | martinvonz | ||
Closed | martinvonz | ||
Closed | martinvonz | ||
Closed | martinvonz | ||
Closed | martinvonz | ||
Closed | martinvonz | ||
Closed | martinvonz | ||
Closed | martinvonz |
if len(ps) > 1: | if len(ps) > 1: | ||||
p2 = repo[ps[1]] | p2 = repo[ps[1]] | ||||
pa = p1.ancestor(p2) | pa = p1.ancestor(p2) | ||||
base, local, other = [ | base, local, other = [ | ||||
x[fn].data() for x in (pa, p1, p2) | x[fn].data() for x in (pa, p1, p2) | ||||
] | ] | ||||
m3 = simplemerge.Merge3Text(base, local, other) | m3 = simplemerge.Merge3Text(base, local, other) | ||||
ml = [ | ml = [ | ||||
l.strip() for l in simplemerge.render_markers(m3)[0] | l.strip() | ||||
for l in simplemerge.render_minimized(m3)[0] | |||||
] | ] | ||||
ml.append(b"") | ml.append(b"") | ||||
elif at > 0: | elif at > 0: | ||||
ml = p1[fn].data().split(b"\n") | ml = p1[fn].data().split(b"\n") | ||||
else: | else: | ||||
ml = initialmergedlines | ml = initialmergedlines | ||||
ml[id * linesperrev] += b" r%i" % id | ml[id * linesperrev] += b" r%i" % id | ||||
mergedtext = b"\n".join(ml) | mergedtext = b"\n".join(ml) |
if len(m3.a) > 0: | if len(m3.a) > 0: | ||||
if m3.a[0].endswith(b'\r\n'): | if m3.a[0].endswith(b'\r\n'): | ||||
return b'\r\n' | return b'\r\n' | ||||
elif m3.a[0].endswith(b'\r'): | elif m3.a[0].endswith(b'\r'): | ||||
return b'\r' | return b'\r' | ||||
return b'\n' | return b'\n' | ||||
def render_markers( | def render_minimized( | ||||
m3, | m3, | ||||
name_a=None, | name_a=None, | ||||
name_b=None, | name_b=None, | ||||
start_marker=b'<<<<<<<', | start_marker=b'<<<<<<<', | ||||
mid_marker=b'=======', | mid_marker=b'=======', | ||||
end_marker=b'>>>>>>>', | end_marker=b'>>>>>>>', | ||||
minimize=False, | |||||
): | ): | ||||
"""Return merge in cvs-like form.""" | """Return merge in cvs-like form.""" | ||||
newline = _detect_newline(m3) | newline = _detect_newline(m3) | ||||
conflicts = False | conflicts = False | ||||
if name_a and start_marker: | if name_a: | ||||
start_marker = start_marker + b' ' + name_a | start_marker = start_marker + b' ' + name_a | ||||
if name_b and end_marker: | if name_b: | ||||
end_marker = end_marker + b' ' + name_b | end_marker = end_marker + b' ' + name_b | ||||
merge_groups = m3.merge_groups() | merge_groups = m3.merge_groups() | ||||
if minimize: | |||||
merge_groups = m3.minimize(merge_groups) | merge_groups = m3.minimize(merge_groups) | ||||
lines = [] | lines = [] | ||||
for what, group_lines in merge_groups: | for what, group_lines in merge_groups: | ||||
if what == b'conflict': | if what == b'conflict': | ||||
base_lines, a_lines, b_lines = group_lines | base_lines, a_lines, b_lines = group_lines | ||||
conflicts = True | conflicts = True | ||||
if start_marker is not None: | |||||
lines.append(start_marker + newline) | lines.append(start_marker + newline) | ||||
lines.extend(a_lines) | lines.extend(a_lines) | ||||
if mid_marker is not None: | |||||
lines.append(mid_marker + newline) | lines.append(mid_marker + newline) | ||||
lines.extend(b_lines) | lines.extend(b_lines) | ||||
if end_marker is not None: | |||||
lines.append(end_marker + newline) | lines.append(end_marker + newline) | ||||
else: | else: | ||||
lines.extend(group_lines) | lines.extend(group_lines) | ||||
return lines, conflicts | return lines, conflicts | ||||
def render_merge3(m3, name_a, name_b, name_base): | def render_merge3(m3, name_a, name_b, name_base): | ||||
"""Render conflicts as 3-way conflict markers.""" | """Render conflicts as 3-way conflict markers.""" | ||||
newline = _detect_newline(m3) | newline = _detect_newline(m3) | ||||
lines = _resolve(m3, (2,)) | lines = _resolve(m3, (2,)) | ||||
else: | else: | ||||
name_a, name_b, name_base = _picklabels(opts.get('label', [])) | name_a, name_b, name_base = _picklabels(opts.get('label', [])) | ||||
if mode == b'mergediff': | if mode == b'mergediff': | ||||
lines, conflicts = render_mergediff(m3, name_a, name_b, name_base) | lines, conflicts = render_mergediff(m3, name_a, name_b, name_base) | ||||
elif mode == b'merge3': | elif mode == b'merge3': | ||||
lines, conflicts = render_merge3(m3, name_a, name_b, name_base) | lines, conflicts = render_merge3(m3, name_a, name_b, name_base) | ||||
else: | else: | ||||
extrakwargs = { | lines, conflicts = render_minimized(m3, name_a, name_b) | ||||
'minimize': True, | |||||
} | |||||
lines, conflicts = render_markers( | |||||
m3, name_a=name_a, name_b=name_b, **extrakwargs | |||||
) | |||||
mergedtext = b''.join(lines) | mergedtext = b''.join(lines) | ||||
if opts.get('print'): | if opts.get('print'): | ||||
ui.fout.write(mergedtext) | ui.fout.write(mergedtext) | ||||
else: | else: | ||||
# localctx.flags() already has the merged flags (done in | # localctx.flags() already has the merged flags (done in | ||||
# mergestate.resolve()) | # mergestate.resolve()) | ||||
localctx.write(mergedtext, localctx.flags()) | localctx.write(mergedtext, localctx.flags()) | ||||
if conflicts: | if conflicts: | ||||
return 1 | return 1 |
m3 = Merge3([], [b'aaa', b'bbb'], []) | m3 = Merge3([], [b'aaa', b'bbb'], []) | ||||
# todo: should use a sentinel at end as from get_matching_blocks | # todo: should use a sentinel at end as from get_matching_blocks | ||||
# to match without zz | # to match without zz | ||||
self.assertEqual(list(m3.find_sync_regions()), [(0, 0, 2, 2, 0, 0)]) | self.assertEqual(list(m3.find_sync_regions()), [(0, 0, 2, 2, 0, 0)]) | ||||
self.assertEqual(list(m3.merge_regions()), [(b'a', 0, 2)]) | self.assertEqual(list(m3.merge_regions()), [(b'a', 0, 2)]) | ||||
self.assertEqual( | self.assertEqual( | ||||
simplemerge.render_markers(m3), ([b'aaa', b'bbb'], False) | simplemerge.render_minimized(m3), ([b'aaa', b'bbb'], False) | ||||
) | ) | ||||
def test_no_conflicts(self): | def test_no_conflicts(self): | ||||
"""No conflicts because only one side changed""" | """No conflicts because only one side changed""" | ||||
m3 = Merge3( | m3 = Merge3( | ||||
[b'aaa', b'bbb'], [b'aaa', b'111', b'bbb'], [b'aaa', b'bbb'] | [b'aaa', b'bbb'], [b'aaa', b'111', b'bbb'], [b'aaa', b'bbb'] | ||||
) | ) | ||||
def test_append_a(self): | def test_append_a(self): | ||||
m3 = Merge3( | m3 = Merge3( | ||||
[b'aaa\n', b'bbb\n'], | [b'aaa\n', b'bbb\n'], | ||||
[b'aaa\n', b'bbb\n', b'222\n'], | [b'aaa\n', b'bbb\n', b'222\n'], | ||||
[b'aaa\n', b'bbb\n'], | [b'aaa\n', b'bbb\n'], | ||||
) | ) | ||||
self.assertEqual( | self.assertEqual( | ||||
b''.join(simplemerge.render_markers(m3)[0]), b'aaa\nbbb\n222\n' | b''.join(simplemerge.render_minimized(m3)[0]), b'aaa\nbbb\n222\n' | ||||
) | ) | ||||
def test_append_b(self): | def test_append_b(self): | ||||
m3 = Merge3( | m3 = Merge3( | ||||
[b'aaa\n', b'bbb\n'], | [b'aaa\n', b'bbb\n'], | ||||
[b'aaa\n', b'bbb\n'], | [b'aaa\n', b'bbb\n'], | ||||
[b'aaa\n', b'bbb\n', b'222\n'], | [b'aaa\n', b'bbb\n', b'222\n'], | ||||
) | ) | ||||
self.assertEqual( | self.assertEqual( | ||||
b''.join(simplemerge.render_markers(m3)[0]), b'aaa\nbbb\n222\n' | b''.join(simplemerge.render_minimized(m3)[0]), b'aaa\nbbb\n222\n' | ||||
) | ) | ||||
def test_append_agreement(self): | def test_append_agreement(self): | ||||
m3 = Merge3( | m3 = Merge3( | ||||
[b'aaa\n', b'bbb\n'], | [b'aaa\n', b'bbb\n'], | ||||
[b'aaa\n', b'bbb\n', b'222\n'], | [b'aaa\n', b'bbb\n', b'222\n'], | ||||
[b'aaa\n', b'bbb\n', b'222\n'], | [b'aaa\n', b'bbb\n', b'222\n'], | ||||
) | ) | ||||
self.assertEqual( | self.assertEqual( | ||||
b''.join(simplemerge.render_markers(m3)[0]), b'aaa\nbbb\n222\n' | b''.join(simplemerge.render_minimized(m3)[0]), b'aaa\nbbb\n222\n' | ||||
) | ) | ||||
def test_append_clash(self): | def test_append_clash(self): | ||||
m3 = Merge3( | m3 = Merge3( | ||||
[b'aaa\n', b'bbb\n'], | [b'aaa\n', b'bbb\n'], | ||||
[b'aaa\n', b'bbb\n', b'222\n'], | [b'aaa\n', b'bbb\n', b'222\n'], | ||||
[b'aaa\n', b'bbb\n', b'333\n'], | [b'aaa\n', b'bbb\n', b'333\n'], | ||||
) | ) | ||||
ml, conflicts = simplemerge.render_markers( | ml, conflicts = simplemerge.render_minimized( | ||||
m3, | m3, | ||||
name_a=b'a', | name_a=b'a', | ||||
name_b=b'b', | name_b=b'b', | ||||
start_marker=b'<<', | start_marker=b'<<', | ||||
mid_marker=b'--', | mid_marker=b'--', | ||||
end_marker=b'>>', | end_marker=b'>>', | ||||
) | ) | ||||
self.assertEqual( | self.assertEqual( | ||||
b''.join(ml), | b''.join(ml), | ||||
b'aaa\n' b'bbb\n' b'<< a\n' b'222\n' b'--\n' b'333\n' b'>> b\n', | b'aaa\n' b'bbb\n' b'<< a\n' b'222\n' b'--\n' b'333\n' b'>> b\n', | ||||
) | ) | ||||
def test_insert_agreement(self): | def test_insert_agreement(self): | ||||
m3 = Merge3( | m3 = Merge3( | ||||
[b'aaa\n', b'bbb\n'], | [b'aaa\n', b'bbb\n'], | ||||
[b'aaa\n', b'222\n', b'bbb\n'], | [b'aaa\n', b'222\n', b'bbb\n'], | ||||
[b'aaa\n', b'222\n', b'bbb\n'], | [b'aaa\n', b'222\n', b'bbb\n'], | ||||
) | ) | ||||
ml, conflicts = simplemerge.render_markers( | ml, conflicts = simplemerge.render_minimized( | ||||
m3, | m3, | ||||
name_a=b'a', | name_a=b'a', | ||||
name_b=b'b', | name_b=b'b', | ||||
start_marker=b'<<', | start_marker=b'<<', | ||||
mid_marker=b'--', | mid_marker=b'--', | ||||
end_marker=b'>>', | end_marker=b'>>', | ||||
) | ) | ||||
self.assertEqual(b''.join(ml), b'aaa\n222\nbbb\n') | self.assertEqual(b''.join(ml), b'aaa\n222\nbbb\n') | ||||
list(m3.merge_groups()), | list(m3.merge_groups()), | ||||
[ | [ | ||||
(b'unchanged', [b'aaa\n']), | (b'unchanged', [b'aaa\n']), | ||||
(b'conflict', ([], [b'111\n'], [b'222\n'])), | (b'conflict', ([], [b'111\n'], [b'222\n'])), | ||||
(b'unchanged', [b'bbb\n']), | (b'unchanged', [b'bbb\n']), | ||||
], | ], | ||||
) | ) | ||||
ml, conflicts = simplemerge.render_markers( | ml, conflicts = simplemerge.render_minimized( | ||||
m3, | m3, | ||||
name_a=b'a', | name_a=b'a', | ||||
name_b=b'b', | name_b=b'b', | ||||
start_marker=b'<<', | start_marker=b'<<', | ||||
mid_marker=b'--', | mid_marker=b'--', | ||||
end_marker=b'>>', | end_marker=b'>>', | ||||
) | ) | ||||
self.assertEqual( | self.assertEqual( | ||||
self.assertEqual( | self.assertEqual( | ||||
list(m3.find_sync_regions()), | list(m3.find_sync_regions()), | ||||
[(0, 1, 0, 1, 0, 1), (3, 4, 4, 5, 5, 6), (4, 4, 5, 5, 6, 6)], | [(0, 1, 0, 1, 0, 1), (3, 4, 4, 5, 5, 6), (4, 4, 5, 5, 6, 6)], | ||||
) | ) | ||||
def test_merge_poem(self): | def test_merge_poem(self): | ||||
"""Test case from diff3 manual""" | """Test case from diff3 manual""" | ||||
m3 = Merge3(TZU, LAO, TAO) | m3 = Merge3(TZU, LAO, TAO) | ||||
ml, conflicts = simplemerge.render_markers(m3, b'LAO', b'TAO') | ml, conflicts = simplemerge.render_minimized(m3, b'LAO', b'TAO') | ||||
self.log(b'merge result:') | self.log(b'merge result:') | ||||
self.log(b''.join(ml)) | self.log(b''.join(ml)) | ||||
self.assertEqual(ml, MERGED_RESULT) | self.assertEqual(ml, MERGED_RESULT) | ||||
def test_binary(self): | def test_binary(self): | ||||
with self.assertRaises(error.Abort): | with self.assertRaises(error.Abort): | ||||
Merge3([b'\x00'], [b'a'], [b'b']) | Merge3([b'\x00'], [b'a'], [b'b']) | ||||
def test_dos_text(self): | def test_dos_text(self): | ||||
base_text = b'a\r\n' | base_text = b'a\r\n' | ||||
this_text = b'b\r\n' | this_text = b'b\r\n' | ||||
other_text = b'c\r\n' | other_text = b'c\r\n' | ||||
m3 = Merge3( | m3 = Merge3( | ||||
base_text.splitlines(True), | base_text.splitlines(True), | ||||
other_text.splitlines(True), | other_text.splitlines(True), | ||||
this_text.splitlines(True), | this_text.splitlines(True), | ||||
) | ) | ||||
m_lines, conflicts = simplemerge.render_markers(m3, b'OTHER', b'THIS') | m_lines, conflicts = simplemerge.render_minimized(m3, b'OTHER', b'THIS') | ||||
self.assertEqual( | self.assertEqual( | ||||
b'<<<<<<< OTHER\r\nc\r\n=======\r\nb\r\n' | b'<<<<<<< OTHER\r\nc\r\n=======\r\nb\r\n' | ||||
b'>>>>>>> THIS\r\n'.splitlines(True), | b'>>>>>>> THIS\r\n'.splitlines(True), | ||||
m_lines, | m_lines, | ||||
) | ) | ||||
def test_mac_text(self): | def test_mac_text(self): | ||||
base_text = b'a\r' | base_text = b'a\r' | ||||
this_text = b'b\r' | this_text = b'b\r' | ||||
other_text = b'c\r' | other_text = b'c\r' | ||||
m3 = Merge3( | m3 = Merge3( | ||||
base_text.splitlines(True), | base_text.splitlines(True), | ||||
other_text.splitlines(True), | other_text.splitlines(True), | ||||
this_text.splitlines(True), | this_text.splitlines(True), | ||||
) | ) | ||||
m_lines, conflicts = simplemerge.render_markers(m3, b'OTHER', b'THIS') | m_lines, conflicts = simplemerge.render_minimized(m3, b'OTHER', b'THIS') | ||||
self.assertEqual( | self.assertEqual( | ||||
b'<<<<<<< OTHER\rc\r=======\rb\r' | b'<<<<<<< OTHER\rc\r=======\rb\r' | ||||
b'>>>>>>> THIS\r'.splitlines(True), | b'>>>>>>> THIS\r'.splitlines(True), | ||||
m_lines, | m_lines, | ||||
) | ) | ||||
if __name__ == '__main__': | if __name__ == '__main__': | ||||
import silenttestrunner | import silenttestrunner | ||||
silenttestrunner.main(__name__) | silenttestrunner.main(__name__) |