mirror of
https://github.com/java-diff-utils/java-diff-utils.git
synced 2026-03-13 10:11:17 +08:00
integrated only index result
This commit is contained in:
@@ -98,7 +98,7 @@ public final class DiffUtils {
|
||||
Objects.requireNonNull(revised,"revised must not be null");
|
||||
Objects.requireNonNull(algorithm,"algorithm must not be null");
|
||||
|
||||
return algorithm.diff(original, revised);
|
||||
return Patch.generate(original, revised, algorithm.diff(original, revised));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
38
src/main/java/difflib/algorithm/Change.java
Normal file
38
src/main/java/difflib/algorithm/Change.java
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2017 java-diff-utils.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package difflib.algorithm;
|
||||
|
||||
import difflib.patch.DeltaType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author toben
|
||||
*/
|
||||
public class Change {
|
||||
public final DeltaType deltaType;
|
||||
public final int startOriginal;
|
||||
public final int endOriginal;
|
||||
public final int startRevised;
|
||||
public final int endRevised;
|
||||
|
||||
public Change(DeltaType deltaType, int startOriginal, int endOriginal, int startRevised, int endRevised) {
|
||||
this.deltaType = deltaType;
|
||||
this.startOriginal = startOriginal;
|
||||
this.endOriginal = endOriginal;
|
||||
this.startRevised = startRevised;
|
||||
this.endRevised = endRevised;
|
||||
}
|
||||
}
|
||||
@@ -38,7 +38,7 @@ public interface DiffAlgorithm<T> {
|
||||
* @param revised The revised sequence. Must not be {@code null}.
|
||||
* @return The patch representing the diff of the given sequences. Never {@code null}.
|
||||
*/
|
||||
public default Patch<T> diff(T[] original, T[] revised) throws DiffException {
|
||||
public default List<Change> diff(T[] original, T[] revised) throws DiffException {
|
||||
return diff(Arrays.asList(original), Arrays.asList(revised));
|
||||
}
|
||||
|
||||
@@ -50,5 +50,5 @@ public interface DiffAlgorithm<T> {
|
||||
* @param revised The revised sequence. Must not be {@code null}.
|
||||
* @return The patch representing the diff of the given sequences. Never {@code null}.
|
||||
*/
|
||||
public Patch<T> diff(List<T> original, List<T> revised) throws DiffException;
|
||||
public List<Change> diff(List<T> original, List<T> revised) throws DiffException;
|
||||
}
|
||||
|
||||
@@ -15,13 +15,14 @@
|
||||
*/
|
||||
package difflib.algorithm.jgit;
|
||||
|
||||
import difflib.algorithm.Change;
|
||||
import difflib.algorithm.DiffAlgorithm;
|
||||
import difflib.algorithm.DiffException;
|
||||
import difflib.patch.ChangeDelta;
|
||||
import difflib.patch.Chunk;
|
||||
import difflib.patch.DeleteDelta;
|
||||
import difflib.patch.DeltaType;
|
||||
import difflib.patch.InsertDelta;
|
||||
import difflib.patch.Patch;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.eclipse.jgit.diff.Edit;
|
||||
import org.eclipse.jgit.diff.EditList;
|
||||
@@ -38,24 +39,24 @@ import org.eclipse.jgit.diff.SequenceComparator;
|
||||
public class JGitDiff<T> implements DiffAlgorithm<T> {
|
||||
|
||||
@Override
|
||||
public Patch diff(List<T> original, List<T> revised) throws DiffException {
|
||||
public List<Change> diff(List<T> original, List<T> revised) throws DiffException {
|
||||
EditList diffList = new EditList();
|
||||
diffList.addAll(new HistogramDiff().diff(new DataListComparator<>(), new DataList<>(original), new DataList<>(revised)));
|
||||
Patch<T> patch = new Patch<>();
|
||||
List<Change> patch = new ArrayList<>();
|
||||
for (Edit edit : diffList) {
|
||||
Chunk<T> orgChunk = new Chunk<>(edit.getBeginA(), original.subList(edit.getBeginA(), edit.getEndA()));
|
||||
Chunk<T> revChunk = new Chunk<>(edit.getBeginA(), revised.subList(edit.getBeginB(), edit.getEndB()));
|
||||
DeltaType type = DeltaType.EQUAL;
|
||||
switch (edit.getType()) {
|
||||
case DELETE:
|
||||
patch.addDelta(new DeleteDelta<>(orgChunk, revChunk));
|
||||
type = DeltaType.DELETE;
|
||||
break;
|
||||
case INSERT:
|
||||
patch.addDelta(new InsertDelta<>(orgChunk, revChunk));
|
||||
type = DeltaType.INSERT;
|
||||
break;
|
||||
case REPLACE:
|
||||
patch.addDelta(new ChangeDelta<>(orgChunk, revChunk));
|
||||
type = DeltaType.CHANGE;
|
||||
break;
|
||||
}
|
||||
patch.add(new Change(type,edit.getBeginA(), edit.getEndA(), edit.getBeginB(), edit.getEndB()));
|
||||
}
|
||||
return patch;
|
||||
}
|
||||
|
||||
@@ -19,15 +19,12 @@ limitations under the License.
|
||||
*/
|
||||
package difflib.algorithm.myers;
|
||||
|
||||
import difflib.algorithm.Change;
|
||||
import difflib.algorithm.DifferentiationFailedException;
|
||||
import difflib.algorithm.DiffAlgorithm;
|
||||
import difflib.algorithm.DiffException;
|
||||
import difflib.patch.ChangeDelta;
|
||||
import difflib.patch.Chunk;
|
||||
import difflib.patch.DeleteDelta;
|
||||
import difflib.patch.Delta;
|
||||
import difflib.patch.DeltaType;
|
||||
import difflib.patch.Equalizer;
|
||||
import difflib.patch.InsertDelta;
|
||||
import difflib.patch.Patch;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -71,7 +68,7 @@ public final class MyersDiff<T> implements DiffAlgorithm<T> {
|
||||
* Return empty diff if get the error while procession the difference.
|
||||
*/
|
||||
@Override
|
||||
public Patch<T> diff(final List<T> original, final List<T> revised) throws DiffException {
|
||||
public List<Change> diff(final List<T> original, final List<T> revised) throws DiffException {
|
||||
Objects.requireNonNull(original, "original list must not be null");
|
||||
Objects.requireNonNull(revised, "revised list must not be null");
|
||||
|
||||
@@ -80,8 +77,9 @@ public final class MyersDiff<T> implements DiffAlgorithm<T> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the minimum diffpath that expresses de differences between the original and revised
|
||||
* sequences, according to Gene Myers differencing algorithm.
|
||||
* Computes the minimum diffpath that expresses de differences between the
|
||||
* original and revised sequences, according to Gene Myers differencing
|
||||
* algorithm.
|
||||
*
|
||||
* @param orig The original sequence.
|
||||
* @param rev The revised sequence.
|
||||
@@ -108,9 +106,9 @@ public final class MyersDiff<T> implements DiffAlgorithm<T> {
|
||||
final int kmiddle = middle + k;
|
||||
final int kplus = kmiddle + 1;
|
||||
final int kminus = kmiddle - 1;
|
||||
PathNode prev = null;
|
||||
PathNode prev;
|
||||
int i;
|
||||
|
||||
|
||||
if ((k == -d) || (k != d && diagonal[kminus].i < diagonal[kplus].i)) {
|
||||
i = diagonal[kplus].i;
|
||||
prev = diagonal[kplus];
|
||||
@@ -153,16 +151,16 @@ public final class MyersDiff<T> implements DiffAlgorithm<T> {
|
||||
* @param orig The original sequence.
|
||||
* @param rev The revised sequence.
|
||||
* @return A {@link Patch} script corresponding to the path.
|
||||
* @throws DifferentiationFailedException if a {@link Patch} could not be built from the given
|
||||
* path.
|
||||
* @throws DifferentiationFailedException if a {@link Patch} could not be
|
||||
* built from the given path.
|
||||
*/
|
||||
private Patch<T> buildRevision(PathNode actualPath, List<T> orig, List<T> rev) {
|
||||
private List<Change> buildRevision(PathNode actualPath, List<T> orig, List<T> rev) {
|
||||
Objects.requireNonNull(actualPath, "path is null");
|
||||
Objects.requireNonNull(orig, "original sequence is null");
|
||||
Objects.requireNonNull(rev, "revised sequence is null");
|
||||
|
||||
PathNode path = actualPath;
|
||||
Patch<T> patch = new Patch<>();
|
||||
List<Change> changes = new ArrayList<>();
|
||||
if (path.isSnake()) {
|
||||
path = path.prev;
|
||||
}
|
||||
@@ -177,35 +175,29 @@ public final class MyersDiff<T> implements DiffAlgorithm<T> {
|
||||
int ianchor = path.i;
|
||||
int janchor = path.j;
|
||||
|
||||
Chunk<T> original = new Chunk<>(ianchor, copyOfRange(orig, ianchor, i));
|
||||
Chunk<T> revised = new Chunk<>(janchor, copyOfRange(rev, janchor, j));
|
||||
Delta<T> delta = null;
|
||||
if (original.size() == 0 && revised.size() != 0) {
|
||||
delta = new InsertDelta<>(original, revised);
|
||||
} else if (original.size() > 0 && revised.size() == 0) {
|
||||
delta = new DeleteDelta<>(original, revised);
|
||||
if (ianchor == i && janchor != j) {
|
||||
changes.add(new Change(DeltaType.INSERT, ianchor, i, janchor, j));
|
||||
} else if (ianchor != i && janchor == j) {
|
||||
changes.add(new Change(DeltaType.DELETE, ianchor, i, janchor, j));
|
||||
} else {
|
||||
delta = new ChangeDelta<>(original, revised);
|
||||
changes.add(new Change(DeltaType.CHANGE, ianchor, i, janchor, j));
|
||||
}
|
||||
|
||||
patch.addDelta(delta);
|
||||
// Chunk<T> original = new Chunk<>(ianchor, copyOfRange(orig, ianchor, i));
|
||||
// Chunk<T> revised = new Chunk<>(janchor, copyOfRange(rev, janchor, j));
|
||||
// Delta<T> delta = null;
|
||||
// if (original.size() == 0 && revised.size() != 0) {
|
||||
// delta = new InsertDelta<>(original, revised);
|
||||
// } else if (original.size() > 0 && revised.size() == 0) {
|
||||
// delta = new DeleteDelta<>(original, revised);
|
||||
// } else {
|
||||
// delta = new ChangeDelta<>(original, revised);
|
||||
// }
|
||||
//
|
||||
// patch.addDelta(delta);
|
||||
if (path.isSnake()) {
|
||||
path = path.prev;
|
||||
}
|
||||
}
|
||||
return patch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new list containing the elements returned by {@link List#subList(int, int)}.
|
||||
*
|
||||
* @param original The original sequence. Must not be {@code null}.
|
||||
* @param fromIndex low endpoint (inclusive) of the subList.
|
||||
* @param to high endpoint (exclusive) of the subList.
|
||||
* @return A new list of the specified range within the original list.
|
||||
*
|
||||
*/
|
||||
private List<T> copyOfRange(final List<T> original, final int fromIndex, final int to) {
|
||||
return new ArrayList<>(original.subList(fromIndex, to));
|
||||
return changes;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,25 +33,6 @@ public abstract class Delta<T> {
|
||||
private final Chunk<T> original;
|
||||
private final Chunk<T> revised;
|
||||
|
||||
/**
|
||||
* Specifies the type of the delta.
|
||||
*
|
||||
*/
|
||||
public static enum DeltaType {
|
||||
/**
|
||||
* A change in the original.
|
||||
*/
|
||||
CHANGE,
|
||||
/**
|
||||
* A delete from the original.
|
||||
*/
|
||||
DELETE,
|
||||
/**
|
||||
* An insert into the original.
|
||||
*/
|
||||
INSERT
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct the delta for original and revised chunks
|
||||
*
|
||||
|
||||
40
src/main/java/difflib/patch/DeltaType.java
Normal file
40
src/main/java/difflib/patch/DeltaType.java
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2017 java-diff-utils.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package difflib.patch;
|
||||
|
||||
/**
|
||||
* Specifies the type of the delta.
|
||||
*
|
||||
*/
|
||||
public enum DeltaType {
|
||||
/**
|
||||
* A change in the original.
|
||||
*/
|
||||
CHANGE,
|
||||
/**
|
||||
* A delete from the original.
|
||||
*/
|
||||
DELETE,
|
||||
/**
|
||||
* An insert into the original.
|
||||
*/
|
||||
INSERT,
|
||||
|
||||
/**
|
||||
* An do nothing.
|
||||
*/
|
||||
EQUAL
|
||||
}
|
||||
@@ -19,6 +19,10 @@ limitations under the License.
|
||||
*/
|
||||
package difflib.patch;
|
||||
|
||||
import difflib.algorithm.Change;
|
||||
import static difflib.patch.DeltaType.DELETE;
|
||||
import static difflib.patch.DeltaType.INSERT;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import static java.util.Comparator.comparing;
|
||||
import java.util.LinkedList;
|
||||
@@ -90,4 +94,24 @@ public final class Patch<T> {
|
||||
public String toString() {
|
||||
return "Patch{" + "deltas=" + deltas + '}';
|
||||
}
|
||||
|
||||
public static <T> Patch<T> generate(List<T> original, List<T> revised, List<Change> changes) {
|
||||
Patch<T> patch = new Patch<>();
|
||||
for (Change change : changes) {
|
||||
Chunk<T> orgChunk = new Chunk<>(change.startOriginal, new ArrayList<>(original.subList(change.startOriginal, change.endOriginal)));
|
||||
Chunk<T> revChunk = new Chunk<>(change.startOriginal, new ArrayList<>(revised.subList(change.startRevised, change.endRevised)));
|
||||
switch (change.deltaType) {
|
||||
case DELETE:
|
||||
patch.addDelta(new DeleteDelta<>(orgChunk, revChunk));
|
||||
break;
|
||||
case INSERT:
|
||||
patch.addDelta(new InsertDelta<>(orgChunk, revChunk));
|
||||
break;
|
||||
case CHANGE:
|
||||
patch.addDelta(new ChangeDelta<>(orgChunk, revChunk));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return patch;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ public class JGitDiffTest {
|
||||
public void testDiff() throws DiffException, PatchFailedException {
|
||||
List<String> orgList = Arrays.asList("A","B","C","A","B","B","A");
|
||||
List<String> revList = Arrays.asList("C","B","A","B","A","C");
|
||||
final Patch<String> patch = new JGitDiff().diff(orgList, revList);
|
||||
final Patch<String> patch = Patch.generate(orgList, revList, new JGitDiff().diff(orgList, revList));
|
||||
System.out.println(patch);
|
||||
assertNotNull(patch);
|
||||
assertEquals(3, patch.getDeltas().size());
|
||||
|
||||
@@ -63,7 +63,7 @@ public class LRJGitDiffTest {
|
||||
List<String> original = readStringListFromInputStream(zip.getInputStream(zip.getEntry("ta")));
|
||||
List<String> revised = readStringListFromInputStream(zip.getInputStream(zip.getEntry("tb")));
|
||||
|
||||
Patch<String> patch = new JGitDiff().diff(original, revised);
|
||||
Patch<String> patch = Patch.generate(original, revised, new JGitDiff().diff(original, revised));
|
||||
|
||||
assertEquals(34, patch.getDeltas().size());
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ import difflib.DiffUtils;
|
||||
import difflib.algorithm.DiffException;
|
||||
import difflib.patch.Patch;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
@@ -31,36 +32,34 @@ import static org.junit.Assert.*;
|
||||
* @author tw
|
||||
*/
|
||||
public class MyersDiffTest {
|
||||
|
||||
|
||||
public MyersDiffTest() {
|
||||
}
|
||||
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpClass() {
|
||||
}
|
||||
|
||||
|
||||
@AfterClass
|
||||
public static void tearDownClass() {
|
||||
}
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
}
|
||||
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testDiffMyersExample1Forward() throws DiffException {
|
||||
final Patch<String> patch = new MyersDiff<String>().diff(
|
||||
Arrays.asList("A","B","C","A","B","B","A"),
|
||||
Arrays.asList("C","B","A","B","A","C"));
|
||||
List<String> original = Arrays.asList("A", "B", "C", "A", "B", "B", "A");
|
||||
List<String> revised = Arrays.asList("C", "B", "A", "B", "A", "C");
|
||||
final Patch<String> patch = Patch.generate(original, revised, new MyersDiff<String>().diff(original, revised));
|
||||
assertNotNull(patch);
|
||||
assertEquals(4, patch.getDeltas().size());
|
||||
assertEquals("Patch{deltas=[[DeleteDelta, position: 0, lines: [A, B]], [InsertDelta, position: 3, lines: [B]], [DeleteDelta, position: 5, lines: [B]], [InsertDelta, position: 7, lines: [C]]]}", patch.toString());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user