simplemerge: make merge_lines() a free function
authorMartin von Zweigbergk <martinvonz@google.com>
Fri, 07 Jan 2022 22:16:22 -0800
changeset 48557 c6649c53073f
parent 48556 ce8c82a5cd65
child 48558 2dbee604a4f0
simplemerge: make merge_lines() a free function IMO, the rendering of a conflict as text with merge markers should be separate from the code for resolving conflicts. The latter is what `Merge3Text` is mostly about already. Differential Revision: https://phab.mercurial-scm.org/D11974
mercurial/debugcommands.py
mercurial/simplemerge.py
tests/test-simplemerge.py
--- a/mercurial/debugcommands.py	Fri Jan 07 18:42:31 2022 -0800
+++ b/mercurial/debugcommands.py	Fri Jan 07 22:16:22 2022 -0800
@@ -272,7 +272,7 @@
                             x[fn].data() for x in (pa, p1, p2)
                         ]
                         m3 = simplemerge.Merge3Text(base, local, other)
-                        ml = [l.strip() for l in m3.merge_lines()[0]]
+                        ml = [l.strip() for l in simplemerge.merge_lines(m3)[0]]
                         ml.append(b"")
                     elif at > 0:
                         ml = p1[fn].data().split(b"\n")
--- a/mercurial/simplemerge.py	Fri Jan 07 18:42:31 2022 -0800
+++ b/mercurial/simplemerge.py	Fri Jan 07 22:16:22 2022 -0800
@@ -87,54 +87,6 @@
         self.a = a
         self.b = b
 
-    def merge_lines(
-        self,
-        name_a=None,
-        name_b=None,
-        name_base=None,
-        start_marker=b'<<<<<<<',
-        mid_marker=b'=======',
-        end_marker=b'>>>>>>>',
-        base_marker=None,
-        minimize=False,
-    ):
-        """Return merge in cvs-like form."""
-        conflicts = False
-        newline = b'\n'
-        if len(self.a) > 0:
-            if self.a[0].endswith(b'\r\n'):
-                newline = b'\r\n'
-            elif self.a[0].endswith(b'\r'):
-                newline = b'\r'
-        if name_a and start_marker:
-            start_marker = start_marker + b' ' + name_a
-        if name_b and end_marker:
-            end_marker = end_marker + b' ' + name_b
-        if name_base and base_marker:
-            base_marker = base_marker + b' ' + name_base
-        merge_groups = self.merge_groups()
-        if minimize:
-            merge_groups = self.minimize(merge_groups)
-        lines = []
-        for what, group_lines in merge_groups:
-            if what == b'conflict':
-                base_lines, a_lines, b_lines = group_lines
-                conflicts = True
-                if start_marker is not None:
-                    lines.append(start_marker + newline)
-                lines.extend(a_lines)
-                if base_marker is not None:
-                    lines.append(base_marker + newline)
-                    lines.extend(base_lines)
-                if mid_marker is not None:
-                    lines.append(mid_marker + newline)
-                lines.extend(b_lines)
-                if end_marker is not None:
-                    lines.append(end_marker + newline)
-            else:
-                lines.extend(group_lines)
-        return lines, conflicts
-
     def merge_groups(self):
         """Yield sequence of line groups.  Each one is a tuple:
 
@@ -389,6 +341,55 @@
     return result
 
 
+def merge_lines(
+    m3,
+    name_a=None,
+    name_b=None,
+    name_base=None,
+    start_marker=b'<<<<<<<',
+    mid_marker=b'=======',
+    end_marker=b'>>>>>>>',
+    base_marker=None,
+    minimize=False,
+):
+    """Return merge in cvs-like form."""
+    conflicts = False
+    newline = b'\n'
+    if len(m3.a) > 0:
+        if m3.a[0].endswith(b'\r\n'):
+            newline = b'\r\n'
+        elif m3.a[0].endswith(b'\r'):
+            newline = b'\r'
+    if name_a and start_marker:
+        start_marker = start_marker + b' ' + name_a
+    if name_b and end_marker:
+        end_marker = end_marker + b' ' + name_b
+    if name_base and base_marker:
+        base_marker = base_marker + b' ' + name_base
+    merge_groups = m3.merge_groups()
+    if minimize:
+        merge_groups = m3.minimize(merge_groups)
+    lines = []
+    for what, group_lines in merge_groups:
+        if what == b'conflict':
+            base_lines, a_lines, b_lines = group_lines
+            conflicts = True
+            if start_marker is not None:
+                lines.append(start_marker + newline)
+            lines.extend(a_lines)
+            if base_marker is not None:
+                lines.append(base_marker + newline)
+                lines.extend(base_lines)
+            if mid_marker is not None:
+                lines.append(mid_marker + newline)
+            lines.extend(b_lines)
+            if end_marker is not None:
+                lines.append(end_marker + newline)
+        else:
+            lines.extend(group_lines)
+    return lines, conflicts
+
+
 def _mergediff(m3, name_a, name_b, name_base):
     lines = []
     conflicts = False
@@ -508,8 +509,8 @@
                 extrakwargs['base_marker'] = b'|||||||'
                 extrakwargs['name_base'] = name_base
                 extrakwargs['minimize'] = False
-            lines, conflicts = m3.merge_lines(
-                name_a=name_a, name_b=name_b, **extrakwargs
+            lines, conflicts = merge_lines(
+                m3, name_a=name_a, name_b=name_b, **extrakwargs
             )
 
     mergedtext = b''.join(lines)
--- a/tests/test-simplemerge.py	Fri Jan 07 18:42:31 2022 -0800
+++ b/tests/test-simplemerge.py	Fri Jan 07 22:16:22 2022 -0800
@@ -179,7 +179,7 @@
 
         self.assertEqual(list(m3.merge_regions()), [(b'a', 0, 2)])
 
-        self.assertEqual(m3.merge_lines(), ([b'aaa', b'bbb'], False))
+        self.assertEqual(simplemerge.merge_lines(m3), ([b'aaa', b'bbb'], False))
 
     def test_no_conflicts(self):
         """No conflicts because only one side changed"""
@@ -204,7 +204,9 @@
             [b'aaa\n', b'bbb\n'],
         )
 
-        self.assertEqual(b''.join(m3.merge_lines()[0]), b'aaa\nbbb\n222\n')
+        self.assertEqual(
+            b''.join(simplemerge.merge_lines(m3)[0]), b'aaa\nbbb\n222\n'
+        )
 
     def test_append_b(self):
         m3 = Merge3(
@@ -213,7 +215,9 @@
             [b'aaa\n', b'bbb\n', b'222\n'],
         )
 
-        self.assertEqual(b''.join(m3.merge_lines()[0]), b'aaa\nbbb\n222\n')
+        self.assertEqual(
+            b''.join(simplemerge.merge_lines(m3)[0]), b'aaa\nbbb\n222\n'
+        )
 
     def test_append_agreement(self):
         m3 = Merge3(
@@ -222,7 +226,9 @@
             [b'aaa\n', b'bbb\n', b'222\n'],
         )
 
-        self.assertEqual(b''.join(m3.merge_lines()[0]), b'aaa\nbbb\n222\n')
+        self.assertEqual(
+            b''.join(simplemerge.merge_lines(m3)[0]), b'aaa\nbbb\n222\n'
+        )
 
     def test_append_clash(self):
         m3 = Merge3(
@@ -231,7 +237,8 @@
             [b'aaa\n', b'bbb\n', b'333\n'],
         )
 
-        ml, conflicts = m3.merge_lines(
+        ml, conflicts = simplemerge.merge_lines(
+            m3,
             name_a=b'a',
             name_b=b'b',
             start_marker=b'<<',
@@ -250,7 +257,8 @@
             [b'aaa\n', b'222\n', b'bbb\n'],
         )
 
-        ml, conflicts = m3.merge_lines(
+        ml, conflicts = simplemerge.merge_lines(
+            m3,
             name_a=b'a',
             name_b=b'b',
             start_marker=b'<<',
@@ -290,7 +298,8 @@
             ],
         )
 
-        ml, conflicts = m3.merge_lines(
+        ml, conflicts = simplemerge.merge_lines(
+            m3,
             name_a=b'a',
             name_b=b'b',
             start_marker=b'<<',
@@ -338,7 +347,7 @@
     def test_merge_poem(self):
         """Test case from diff3 manual"""
         m3 = Merge3(TZU, LAO, TAO)
-        ml, conflicts = m3.merge_lines(b'LAO', b'TAO')
+        ml, conflicts = simplemerge.merge_lines(m3, b'LAO', b'TAO')
         self.log(b'merge result:')
         self.log(b''.join(ml))
         self.assertEqual(ml, MERGED_RESULT)
@@ -356,7 +365,7 @@
             other_text.splitlines(True),
             this_text.splitlines(True),
         )
-        m_lines, conflicts = m3.merge_lines(b'OTHER', b'THIS')
+        m_lines, conflicts = simplemerge.merge_lines(m3, b'OTHER', b'THIS')
         self.assertEqual(
             b'<<<<<<< OTHER\r\nc\r\n=======\r\nb\r\n'
             b'>>>>>>> THIS\r\n'.splitlines(True),
@@ -372,7 +381,7 @@
             other_text.splitlines(True),
             this_text.splitlines(True),
         )
-        m_lines, conflicts = m3.merge_lines(b'OTHER', b'THIS')
+        m_lines, conflicts = simplemerge.merge_lines(m3, b'OTHER', b'THIS')
         self.assertEqual(
             b'<<<<<<< OTHER\rc\r=======\rb\r'
             b'>>>>>>> THIS\r'.splitlines(True),