Details
Details
Diff Detail
Diff Detail
- Repository
- rHG Mercurial
- Lint
Automatic diff as part of commit; lint not applicable. - Unit
Automatic diff as part of commit; unit tests not applicable.
( )
| Automatic diff as part of commit; lint not applicable. |
| Automatic diff as part of commit; unit tests not applicable. |
| Path | Packages | |||
|---|---|---|---|---|
| M | mercurial/debugcommands.py (4 lines) | |||
| M | mercurial/simplemerge.py (8 lines) | |||
| M | tests/test-simplemerge.py (22 lines) |
| 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 |
| p1 = repo[ps[0]] | p1 = repo[ps[0]] | ||||
| 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 = [l.strip() for l in simplemerge.merge_lines(m3)[0]] | ml = [ | ||||
| l.strip() for l in simplemerge.render_markers(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) | ||||
| files.append(fn) | files.append(fn) | ||||
| if len(overrides) > 3: | if len(overrides) > 3: | ||||
| raise error.Abort(_(b"can only specify three labels.")) | raise error.Abort(_(b"can only specify three labels.")) | ||||
| result = defaults[:] | result = defaults[:] | ||||
| for i, override in enumerate(overrides): | for i, override in enumerate(overrides): | ||||
| result[i] = override | result[i] = override | ||||
| return result | return result | ||||
| def merge_lines( | def render_markers( | ||||
| m3, | m3, | ||||
| name_a=None, | name_a=None, | ||||
| name_b=None, | name_b=None, | ||||
| name_base=None, | name_base=None, | ||||
| start_marker=b'<<<<<<<', | start_marker=b'<<<<<<<', | ||||
| mid_marker=b'=======', | mid_marker=b'=======', | ||||
| end_marker=b'>>>>>>>', | end_marker=b'>>>>>>>', | ||||
| base_marker=None, | base_marker=None, | ||||
| lines.extend(b_lines) | lines.extend(b_lines) | ||||
| if end_marker is not None: | 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 _mergediff(m3, name_a, name_b, name_base): | def render_mergediff(m3, name_a, name_b, name_base): | ||||
| lines = [] | lines = [] | ||||
| conflicts = False | conflicts = False | ||||
| for what, group_lines in m3.merge_groups(): | for what, group_lines in m3.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 | ||||
| base_text = b''.join(base_lines) | base_text = b''.join(base_lines) | ||||
| b_blocks = list( | b_blocks = list( | ||||
| mdiff.allblocks( | mdiff.allblocks( | ||||
| lines = _resolve(m3, (1,)) | lines = _resolve(m3, (1,)) | ||||
| elif mode == b'other': | elif mode == b'other': | ||||
| lines = _resolve(m3, (2,)) | lines = _resolve(m3, (2,)) | ||||
| else: | else: | ||||
| name_a, name_b, name_base = _picklabels( | name_a, name_b, name_base = _picklabels( | ||||
| [localctx.path(), otherctx.path(), None], opts.get('label', []) | [localctx.path(), otherctx.path(), None], opts.get('label', []) | ||||
| ) | ) | ||||
| if mode == b'mergediff': | if mode == b'mergediff': | ||||
| lines, conflicts = _mergediff(m3, name_a, name_b, name_base) | lines, conflicts = render_mergediff(m3, name_a, name_b, name_base) | ||||
| else: | else: | ||||
| extrakwargs = { | extrakwargs = { | ||||
| 'minimize': True, | 'minimize': True, | ||||
| } | } | ||||
| if mode == b'merge3': | if mode == b'merge3': | ||||
| extrakwargs['base_marker'] = b'|||||||' | extrakwargs['base_marker'] = b'|||||||' | ||||
| extrakwargs['name_base'] = name_base | extrakwargs['name_base'] = name_base | ||||
| extrakwargs['minimize'] = False | extrakwargs['minimize'] = False | ||||
| lines, conflicts = merge_lines( | lines, conflicts = render_markers( | ||||
| m3, name_a=name_a, name_b=name_b, **extrakwargs | 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 | ||||
| def test_null_insert(self): | def test_null_insert(self): | ||||
| 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(simplemerge.merge_lines(m3), ([b'aaa', b'bbb'], False)) | self.assertEqual( | ||||
| simplemerge.render_markers(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'] | ||||
| ) | ) | ||||
| self.assertEqual( | self.assertEqual( | ||||
| 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.merge_lines(m3)[0]), b'aaa\nbbb\n222\n' | b''.join(simplemerge.render_markers(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.merge_lines(m3)[0]), b'aaa\nbbb\n222\n' | b''.join(simplemerge.render_markers(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.merge_lines(m3)[0]), b'aaa\nbbb\n222\n' | b''.join(simplemerge.render_markers(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.merge_lines( | ml, conflicts = simplemerge.render_markers( | ||||
| 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.merge_lines( | ml, conflicts = simplemerge.render_markers( | ||||
| 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.merge_lines( | ml, conflicts = simplemerge.render_markers( | ||||
| 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.merge_lines(m3, b'LAO', b'TAO') | ml, conflicts = simplemerge.render_markers(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.merge_lines(m3, b'OTHER', b'THIS') | m_lines, conflicts = simplemerge.render_markers(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.merge_lines(m3, b'OTHER', b'THIS') | m_lines, conflicts = simplemerge.render_markers(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__) | ||||