[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