Iterator<Edit> baseToOurs = oursEdits.iterator();
EditList theirsEdits = new MyersDiff(base, theirs).getEdits();
Iterator<Edit> baseToTheirs = theirsEdits.iterator();
int current = 0; // points to the next line (first line is 0) of base
// which was not handled yet
Edit oursEdit = nextEdit(baseToOurs);
Edit theirsEdit = nextEdit(baseToTheirs);
// iterate over all edits from base to ours and from base to theirs
// leave the loop when there are no edits more for ours or for theirs
// (or both)
while (theirsEdit != END_EDIT || oursEdit != END_EDIT) {
if (oursEdit.getEndA() <= theirsEdit.getBeginA()) {
// something was changed in ours not overlapping with any change
// from theirs. First add the common part in front of the edit
// then the edit.
if (current != oursEdit.getBeginA()) {
result.add(0, current, oursEdit.getBeginA(),
ConflictState.NO_CONFLICT);
}
result.add(1, oursEdit.getBeginB(), oursEdit.getEndB(),
ConflictState.NO_CONFLICT);
current = oursEdit.getEndA();
oursEdit = nextEdit(baseToOurs);
} else if (theirsEdit.getEndA() <= oursEdit.getBeginA()) {
// something was changed in theirs not overlapping with any
// from ours. First add the common part in front of the edit
// then the edit.
if (current != theirsEdit.getBeginA()) {
result.add(0, current, theirsEdit.getBeginA(),
ConflictState.NO_CONFLICT);
}
result.add(2, theirsEdit.getBeginB(), theirsEdit.getEndB(),
ConflictState.NO_CONFLICT);
current = theirsEdit.getEndA();
theirsEdit = nextEdit(baseToTheirs);
} else {
// here we found a real overlapping modification
// if there is a common part in front of the conflict add it
if (oursEdit.getBeginA() != current
&& theirsEdit.getBeginA() != current) {
result.add(0, current, Math.min(oursEdit.getBeginA(),
theirsEdit.getBeginA()), ConflictState.NO_CONFLICT);
}
// set some initial values for the ranges in A and B which we
// want to handle
int oursBeginB = oursEdit.getBeginB();
int theirsBeginB = theirsEdit.getBeginB();
// harmonize the start of the ranges in A and B
if (oursEdit.getBeginA() < theirsEdit.getBeginA()) {
theirsBeginB -= theirsEdit.getBeginA()
- oursEdit.getBeginA();
} else {
oursBeginB -= oursEdit.getBeginA() - theirsEdit.getBeginA();
}
// combine edits:
// Maybe an Edit on one side corresponds to multiple Edits on
// the other side. Then we have to combine the Edits of the
// other side - so in the end we can merge together two single
// edits.
//
// It is important to notice that this combining will extend the
// ranges of our conflict always downwards (towards the end of
// the content). The starts of the conflicting ranges in ours
// and theirs are not touched here.
//
// This combining is an iterative process: after we have
// combined some edits we have to do the check again. The
// combined edits could now correspond to multiple edits on the
// other side.
//
// Example: when this combining algorithm works on the following
// edits
// oursEdits=((0-5,0-5),(6-8,6-8),(10-11,10-11)) and
// theirsEdits=((0-1,0-1),(2-3,2-3),(5-7,5-7))
// it will merge them into
// oursEdits=((0-8,0-8),(10-11,10-11)) and
// theirsEdits=((0-7,0-7))
//
// Since the only interesting thing to us is how in ours and
// theirs the end of the conflicting range is changing we let
// oursEdit and theirsEdit point to the last conflicting edit
Edit nextOursEdit = nextEdit(baseToOurs);
Edit nextTheirsEdit = nextEdit(baseToTheirs);
for (;;) {
if (oursEdit.getEndA() > nextTheirsEdit.getBeginA()) {
theirsEdit = nextTheirsEdit;
nextTheirsEdit = nextEdit(baseToTheirs);
} else if (theirsEdit.getEndA() > nextOursEdit.getBeginA()) {
oursEdit = nextOursEdit;
nextOursEdit = nextEdit(baseToOurs);