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__) | ||||