[meld] Refactor auto-merge classes
- From: Kai Willadsen <kaiw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [meld] Refactor auto-merge classes
- Date: Sun, 14 Mar 2010 01:21:53 +0000 (UTC)
commit a72042d6ecfc12e620fc19d16895a08839e5bdf6
Author: Piotr Piastucki <leech miranda gmail com>
Date: Fri Mar 12 11:53:23 2010 +0100
Refactor auto-merge classes
A new class called AutoMergeDiffer is extracted from Merger class to
separate the functionality. AutomMergeDiffer is supposed to be a
drop-in replacement for Differ while Merger class handles file merging
only. This change also prepares ground for adding 2 file merge support
to Merger. Moreover, some redundant code is removed from
AutoMergeDiffer and replaced with a proper call to Differ._auto_merge
meld/filemerge.py | 6 ++--
meld/merge.py | 65 ++++++++++++++++++++++++++---------------------------
2 files changed, 35 insertions(+), 36 deletions(-)
---
diff --git a/meld/filemerge.py b/meld/filemerge.py
index 87349dc..4c24bcd 100644
--- a/meld/filemerge.py
+++ b/meld/filemerge.py
@@ -26,7 +26,7 @@ class FileMerge(filediff.FileDiff):
def __init__(self, prefs, num_panes):
filediff.FileDiff.__init__(self, prefs, num_panes)
- self.linediffer = merge.Merger()
+ self.linediffer = merge.AutoMergeDiffer()
self.hidden_textbuffer = gtk.TextBuffer()
def _connect_buffer_handlers(self):
@@ -71,11 +71,11 @@ class FileMerge(filediff.FileDiff):
filteredpanetext = [self._filter_text(p) for p in panetext]
filteredlines = map(lambda x: x.split("\n"), filteredpanetext)
merger = merge.Merger()
- step = merger.set_sequences_iter(filteredlines)
+ step = merger.initialize(filteredlines, lines)
while step.next() == None:
yield 1
yield _("[%s] Merging files") % self.label_text
- for panetext[1] in merger.merge_file(filteredlines, lines):
+ for panetext[1] in merger.merge_3_files():
yield 1
self.linediffer.unresolved = merger.unresolved
self.textbuffer[1].insert(self.textbuffer[1].get_end_iter(), panetext[1])
diff --git a/meld/merge.py b/meld/merge.py
index 5f0e926..3333f86 100644
--- a/meld/merge.py
+++ b/meld/merge.py
@@ -19,7 +19,7 @@ import matchers
#from _patiencediff_py import PatienceSequenceMatcher_py as PatienceSequenceMatcher
-class Merger(diffutil.Differ):
+class AutoMergeDiffer(diffutil.Differ):
_matcher = matchers.MyersSequenceMatcher
# _matcher = PatienceSequenceMatcher
@@ -30,23 +30,10 @@ class Merger(diffutil.Differ):
self.unresolved = []
def _auto_merge(self, using, texts):
- l0, h0, l1, h1, l2, h2 = self._merge_blocks(using)
-
- if h0 - l0 == h2 - l2 and texts[0][l0:h0] == texts[2][l2:h2]:
- # handle simple conflicts here (exact match)
- if l1 != h1 and l0 == h0:
- tag = "delete"
- elif l1 != h1:
- tag = "replace"
- else:
- tag = "insert"
- out0 = (tag, l1, h1, l0, h0)
- out1 = (tag, l1, h1, l2, h2)
- else:
- # here we will try to resolve more complex conflicts automatically... if possible
- out0 = ('conflict', l1, h1, l0, h0)
- out1 = ('conflict', l1, h1, l2, h2)
- if self.auto_merge:
+ for out0, out1 in diffutil.Differ._auto_merge(self, using, texts):
+ if self.auto_merge and out0[0] == 'conflict':
+ # we will try to resolve more complex conflicts automatically here... if possible
+ l0, h0, l1, h1, l2, h2 = out0[3], out0[4], out0[1], out0[2], out1[3], out1[4]
len0 = h0 - l0
len1 = h1 - l1
len2 = h2 - l2
@@ -145,7 +132,7 @@ class Merger(diffutil.Differ):
out1 = ('conflict', i1, seq1[2], seq1[3], seq1[4])
yield out0, out1
return
- yield out0, out1
+ yield out0, out1
def change_sequence(self, sequence, startidx, sizechange, texts):
if sequence == 1:
@@ -173,6 +160,21 @@ class Merger(diffutil.Differ):
def get_unresolved_count(self):
return len(self.unresolved)
+class Merger(diffutil.Differ):
+
+ def __init__(self, ):
+ self.differ = AutoMergeDiffer()
+ self.differ.auto_merge = True
+ self.differ.unresolved = []
+ self.texts = []
+
+ def initialize(self, sequences, texts):
+ step = self.differ.set_sequences_iter(sequences)
+ while step.next() == None:
+ yield None
+ self.texts = texts
+ yield 1
+
def _apply_change(self, text, change, mergedtext):
LO, HI = 1, 2
if change[0] == 'insert':
@@ -186,15 +188,13 @@ class Merger(diffutil.Differ):
else:
return change[HI] - change[LO]
- def merge_file(self, filteredtexts, texts):
+ def merge_3_files(self):
LO, HI = 1, 2
- self.auto_merge = True
- self.unresolved = unresolved = []
- diffs = self.diffs
+ self.unresolved = []
lastline = 0
mergedline = 0
mergedtext = []
- for change in self._merge_diffs(diffs[0], diffs[1], filteredtexts):
+ for change in self.differ.all_changes():
yield None
low_mark = lastline
if change[0] != None:
@@ -203,32 +203,31 @@ class Merger(diffutil.Differ):
if change[1][LO] > low_mark:
low_mark = change[1][LO]
for i in range(lastline, low_mark, 1):
- mergedtext.append(texts[1][i])
+ mergedtext.append(self.texts[1][i])
mergedline += low_mark - lastline
lastline = low_mark
if change[0] != None and change[1] != None and change[0][0] == 'conflict':
high_mark = max(change[0][HI], change[1][HI])
if low_mark < high_mark:
for i in range(low_mark, high_mark):
- mergedtext.append("(??)" + texts[1][i])
- unresolved.append(mergedline)
+ mergedtext.append("(??)" + self.texts[1][i])
+ self.unresolved.append(mergedline)
mergedline += 1
else:
#conflictsize = min(1, max(change[0][HI + 2] - change[0][LO + 2], change[1][HI + 2] - change[1][LO + 2]))
#for i in range(conflictsize):
mergedtext.append("(??)")
- unresolved.append(mergedline)
+ self.unresolved.append(mergedline)
mergedline += 1
lastline = high_mark
elif change[0] != None:
- lastline += self._apply_change(texts[0], change[0], mergedtext)
+ lastline += self._apply_change(self.texts[0], change[0], mergedtext)
mergedline += change[0][HI + 2] - change[0][LO + 2]
else:
- lastline += self._apply_change(texts[2], change[1], mergedtext)
+ lastline += self._apply_change(self.texts[2], change[1], mergedtext)
mergedline += change[1][HI + 2] - change[1][LO + 2]
- baselen = len(texts[1])
+ baselen = len(self.texts[1])
for i in range(lastline, baselen, 1):
- mergedtext.append(texts[1][i])
+ mergedtext.append(self.texts[1][i])
- self.auto_merge = False
yield "\n".join(mergedtext)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]