Rev 5181: (vila) Extend Merge3 API to also work with objects rather than text lines. (Andrew Bennetts) in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Fri Apr 23 17:57:19 BST 2010


At file:///home/pqm/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 5181 [merge]
revision-id: pqm at pqm.ubuntu.com-20100423165712-y00wbjl9yagw4g3q
parent: pqm at pqm.ubuntu.com-20100423134732-e01c947fwuvjwtl2
parent: andrew.bennetts at canonical.com-20100422140356-zv9iwa7eebxwjh2v
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Fri 2010-04-23 17:57:12 +0100
message:
  (vila) Extend Merge3 API to also work with objects rather than text lines. (Andrew Bennetts)
modified:
  bzrlib/merge3.py               merge3.py-20050704130834-bf0597094828a2e1
  bzrlib/plugins/news_merge/news_merge.py news_merge.py-20100118070008-sb1qe88ha64es7nv-1
  bzrlib/plugins/news_merge/parser.py parser.py-20100113072530-qj0i1em8th5pqhat-4
  bzrlib/tests/test_merge3.py    merge3.py-20050704130834-556689114c89e6f2
=== modified file 'bzrlib/merge3.py'
--- a/bzrlib/merge3.py	2009-03-23 14:59:43 +0000
+++ b/bzrlib/merge3.py	2010-04-19 05:41:54 +0000
@@ -66,10 +66,24 @@
     Given BASE, OTHER, THIS, tries to produce a combined text
     incorporating the changes from both BASE->OTHER and BASE->THIS.
     All three will typically be sequences of lines."""
-    def __init__(self, base, a, b, is_cherrypick=False):
-        check_text_lines(base)
-        check_text_lines(a)
-        check_text_lines(b)
+
+    def __init__(self, base, a, b, is_cherrypick=False, allow_objects=False):
+        """Constructor.
+
+        :param base: lines in BASE
+        :param a: lines in A
+        :param b: lines in B
+        :param is_cherrypick: flag indicating if this merge is a cherrypick.
+            When cherrypicking b => a, matches with b and base do not conflict.
+        :param allow_objects: if True, do not require that base, a and b are
+            plain Python strs.  Also prevents BinaryFile from being raised.
+            Lines can be any sequence of comparable and hashable Python
+            objects.
+        """
+        if not allow_objects:
+            check_text_lines(base)
+            check_text_lines(a)
+            check_text_lines(b)
         self.base = base
         self.a = a
         self.b = b

=== modified file 'bzrlib/plugins/news_merge/news_merge.py'
--- a/bzrlib/plugins/news_merge/news_merge.py	2010-01-28 18:05:44 +0000
+++ b/bzrlib/plugins/news_merge/news_merge.py	2010-04-20 01:53:31 +0000
@@ -17,13 +17,10 @@
 """Merge logic for news_merge plugin."""
 
 
-from bzrlib.plugins.news_merge.parser import simple_parse
+from bzrlib.plugins.news_merge.parser import simple_parse_lines
 from bzrlib import merge, merge3
 
 
-magic_marker = '|NEWS-MERGE-MAGIC-MARKER|'
-
-
 class NewsMerger(merge.ConfigurableFileMerger):
     """Merge bzr NEWS files."""
 
@@ -39,13 +36,12 @@
         # Transform the different versions of the NEWS file into a bunch of
         # text lines where each line matches one part of the overall
         # structure, e.g. a heading or bullet.
-        def munge(lines):
-            return list(blocks_to_fakelines(simple_parse(''.join(lines))))
-        this_lines = munge(params.this_lines)
-        other_lines = munge(params.other_lines)
-        base_lines = munge(params.base_lines)
-        m3 = merge3.Merge3(base_lines, this_lines, other_lines)
-        result_lines = []
+        this_lines = list(simple_parse_lines(params.this_lines))
+        other_lines = list(simple_parse_lines(params.other_lines))
+        base_lines = list(simple_parse_lines(params.base_lines))
+        m3 = merge3.Merge3(base_lines, this_lines, other_lines,
+            allow_objects=True)
+        result_chunks = []
         for group in m3.merge_groups():
             if group[0] == 'conflict':
                 _, base, a, b = group
@@ -53,7 +49,7 @@
                 # this.
                 for line_set in [base, a, b]:
                     for line in line_set:
-                        if not line.startswith('bullet'):
+                        if line[0] != 'bullet':
                             # Something else :(
                             # Maybe the default merge can cope.
                             return 'not_applicable', None
@@ -68,27 +64,13 @@
                     deleted_in_b)
                 # Sort, and emit.
                 final = sorted(final, key=sort_key)
-                result_lines.extend(final)
+                result_chunks.extend(final)
             else:
-                result_lines.extend(group[1])
+                result_chunks.extend(group[1])
         # Transform the merged elements back into real blocks of lines.
-        return 'success', list(fakelines_to_blocks(result_lines))
-
-
-def blocks_to_fakelines(blocks):
-    for kind, text in blocks:
-        yield '%s%s%s' % (kind, magic_marker, text)
-
-
-def fakelines_to_blocks(fakelines):
-    fakelines = list(fakelines)
-    # Strip out the magic_marker, and reinstate the \n\n between blocks
-    for fakeline in fakelines[:-1]:
-        yield fakeline.split(magic_marker, 1)[1] + '\n\n'
-    # The final block doesn't have a trailing \n\n.
-    for fakeline in fakelines[-1:]:
-        yield fakeline.split(magic_marker, 1)[1]
-
-
-def sort_key(s):
-    return s.replace('`', '').lower()
+        result_lines = '\n\n'.join(chunk[1] for chunk in result_chunks)
+        return 'success', result_lines
+
+
+def sort_key(chunk):
+    return chunk[1].replace('`', '').lower()

=== modified file 'bzrlib/plugins/news_merge/parser.py'
--- a/bzrlib/plugins/news_merge/parser.py	2010-01-18 07:00:11 +0000
+++ b/bzrlib/plugins/news_merge/parser.py	2010-04-19 05:41:54 +0000
@@ -25,6 +25,13 @@
 """
 
 
+def simple_parse_lines(lines):
+    """Same as simple_parse, but takes an iterable of strs rather than a single
+    str.
+    """
+    return simple_parse(''.join(lines))
+
+
 def simple_parse(content):
     """Returns blocks, where each block is a 2-tuple (kind, text).
     

=== modified file 'bzrlib/tests/test_merge3.py'
--- a/bzrlib/tests/test_merge3.py	2009-03-23 14:59:43 +0000
+++ b/bzrlib/tests/test_merge3.py	2010-04-22 14:03:56 +0000
@@ -422,3 +422,26 @@
                              'g\n'
                              '>>>>>>>\n',
                              ''.join(m_lines))
+
+    def test_allow_objects(self):
+        """Objects other than strs may be used with Merge3 when
+        allow_objects=True.
+        
+        merge_groups and merge_regions work with non-str input.  Methods that
+        return lines like merge_lines fail.
+        """
+        base = [(x,x) for x in 'abcde']
+        a = [(x,x) for x in 'abcdef']
+        b = [(x,x) for x in 'Zabcde']
+        m3 = Merge3(base, a, b, allow_objects=True)
+        self.assertEqual(
+            [('b', 0, 1),
+             ('unchanged', 0, 5),
+             ('a', 5, 6)],
+            list(m3.merge_regions()))
+        self.assertEqual(
+            [('b', [('Z', 'Z')]),
+             ('unchanged', [(x,x) for x in 'abcde']),
+             ('a', [('f', 'f')])],
+            list(m3.merge_groups()))
+




More information about the bazaar-commits mailing list