[Pkg-bazaar-commits] ./bzr/unstable r821: - start code for built-in diff3-style resolve

Martin Pool mbp at sourcefrog.net
Fri Apr 10 08:21:08 UTC 2009


------------------------------------------------------------
revno: 821
committer: Martin Pool <mbp at sourcefrog.net>
timestamp: Mon 2005-07-04 23:08:55 +1000
message:
  - start code for built-in diff3-style resolve
  
  - test cases for this
added:
  bzrlib/merge3.py
  bzrlib/selftest/merge3.py
modified:
  bzrlib/selftest/__init__.py
-------------- next part --------------
=== added file 'bzrlib/merge3.py'
--- a/bzrlib/merge3.py	1970-01-01 00:00:00 +0000
+++ b/bzrlib/merge3.py	2005-07-04 13:08:55 +0000
@@ -0,0 +1,93 @@
+# Copyright (C) 2004, 2005 by Canonical Ltd
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+
+def intersect(ra, rb):
+    """Given two ranges return the range where they intersect or None.
+
+    >>> intersect((0, 10), (0, 6))
+    (0, 6)
+    >>> intersect((0, 10), (5, 15))
+    (5, 10)
+    >>> intersect((0, 10), (10, 15))
+    >>> intersect((0, 9), (10, 15))
+    >>> intersect((0, 9), (7, 15))
+    (7, 9)
+    """
+    assert ra[0] <= ra[1]
+    assert rb[0] <= rb[1]
+    
+    sa = max(ra[0], rb[0])
+    sb = min(ra[1], rb[1])
+    if sa < sb:
+        return sa, sb
+    else:
+        return None
+
+
+class Merge3(object):
+    """3-way merge of texts.
+
+    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):
+        self.base = base
+        self.a = a
+        self.b = b
+
+        #from difflib import SequenceMatcher
+
+        #self.a_ops = SequenceMatcher(None, self.base, self.a).get_opcodes()
+        #self.b_ops = SequenceMatcher(None, self.base, self.b).get_opcodes()
+
+        
+    def find_conflicts(self):
+        """Return a list of conflict regions.
+
+        Each entry is given as (base1, base2, a1, a2, b1, b2).
+
+        This indicates that the range [base1,base2] can be replaced by either
+        [a1,a2] or [b1,b2].
+        """
+
+
+    def find_unconflicted(self):
+        """Return a list of ranges in base that are not conflicted."""
+        from difflib import SequenceMatcher
+        am = SequenceMatcher(None, self.base, self.a).get_matching_blocks()
+        bm = SequenceMatcher(None, self.base, self.b).get_matching_blocks()
+
+        unc = []
+
+        while am and bm:
+            # there is an unconflicted block at i; how long does it
+            # extend?  until whichever one ends earlier.
+            a1 = am[0][0]
+            a2 = a1 + am[0][2]
+            b1 = bm[0][0]
+            b2 = b1 + bm[0][2]
+            i = intersect((a1, a2), (b1, b2))
+            if i:
+                unc.append(i)
+
+            if a2 < b2:
+                del am[0]
+            else:
+                del bm[0]
+                
+        return unc

=== modified file 'bzrlib/selftest/__init__.py'
--- a/bzrlib/selftest/__init__.py	2005-07-04 05:29:56 +0000
+++ b/bzrlib/selftest/__init__.py	2005-07-04 13:08:55 +0000
@@ -214,6 +214,7 @@
     import bzrlib.selftest.whitebox
     import bzrlib.selftest.blackbox
     import bzrlib.selftest.versioning
+    import bzrlib.selftest.merge3
     import bzrlib.merge_core
     from doctest import DocTestSuite
     import os
@@ -235,11 +236,13 @@
     # the code.
 
     for m in bzrlib.selftest.whitebox, \
-            bzrlib.selftest.versioning:
+            bzrlib.selftest.versioning, \
+            bzrlib.selftest.merge3:
         suite.addTest(tl.loadTestsFromModule(m))
 
     for m in bzrlib.store, bzrlib.inventory, bzrlib.branch, bzrlib.osutils, \
-            bzrlib.commands:
+            bzrlib.commands, \
+            bzrlib.merge3:
         suite.addTest(DocTestSuite(m))
 
     suite.addTest(bzrlib.selftest.blackbox.suite())

=== added file 'bzrlib/selftest/merge3.py'
--- a/bzrlib/selftest/merge3.py	1970-01-01 00:00:00 +0000
+++ b/bzrlib/selftest/merge3.py	2005-07-04 13:08:55 +0000
@@ -0,0 +1,68 @@
+# Copyright (C) 2004, 2005 by Canonical Ltd
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+from bzrlib.selftest import InTempDir, TestBase
+from bzrlib.merge3 import Merge3
+
+class NoConflicts(TestBase):
+    """No conflicts because only one side changed"""
+    def runTest(self):
+        m3 = Merge3(['aaa', 'bbb'],
+                    ['aaa', '111', 'bbb'],
+                    ['aaa', 'bbb'])
+
+        self.assertEquals(m3.find_unconflicted(),
+                          [(0, 1), (1, 2)])
+
+    
+class NoChanges(TestBase):
+    """No conflicts because nothing changed"""
+    def runTest(self):
+        m3 = Merge3(['aaa', 'bbb'],
+                    ['aaa', 'bbb'],
+                    ['aaa', 'bbb'])
+
+        self.assertEquals(m3.find_unconflicted(),
+                          [(0, 2)])
+
+    
+
+class InsertClash(TestBase):
+    """Both try to insert lines in the same place."""
+    def runTest(self):
+        m3 = Merge3(['aaa', 'bbb'],
+                    ['aaa', '111', 'bbb'],
+                    ['aaa', '222', 'bbb'])
+
+        self.assertEquals(m3.find_unconflicted(),
+                          [(0, 1), (1, 2)])
+
+        
+
+
+
+class ReplaceClash(TestBase):
+    """Both try to insert lines in the same place."""
+    def runTest(self):
+        m3 = Merge3(['aaa', '000', 'bbb'],
+                    ['aaa', '111', 'bbb'],
+                    ['aaa', '222', 'bbb'])
+
+        self.assertEquals(m3.find_unconflicted(),
+                          [(0, 1), (2, 3)])
+
+        



More information about the Pkg-bazaar-commits mailing list