mirror of
https://github.com/java-diff-utils/java-diff-utils.git
synced 2026-03-13 10:11:17 +08:00
Introduced a multi module java-diff-utils. The core project now has no more
external dependencies.
This commit is contained in:
19
java-diff-utils-jgit/nb-configuration.xml
Normal file
19
java-diff-utils-jgit/nb-configuration.xml
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project-shared-configuration>
|
||||
<!--
|
||||
This file contains additional configuration written by modules in the NetBeans IDE.
|
||||
The configuration is intended to be shared among all the users of project and
|
||||
therefore it is assumed to be part of version control checkout.
|
||||
Without this configuration present, some functionality in the IDE may be limited or fail altogether.
|
||||
-->
|
||||
<properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1">
|
||||
<!--
|
||||
Properties that influence various parts of the IDE, especially code formatting and the like.
|
||||
You can copy and paste the single properties, into the pom.xml file and the IDE will pick them up.
|
||||
That way multiple projects can share the same settings (useful for formatting rules for example).
|
||||
Any value defined here will override the pom.xml file value but is only applicable to the current project.
|
||||
-->
|
||||
<netbeans.compile.on.save>none</netbeans.compile.on.save>
|
||||
<netbeans.hint.jdkPlatform>JDK_1.8</netbeans.hint.jdkPlatform>
|
||||
</properties>
|
||||
</project-shared-configuration>
|
||||
58
java-diff-utils-jgit/pom.xml
Normal file
58
java-diff-utils-jgit/pom.xml
Normal file
@@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>io.github.java-diff-utils</groupId>
|
||||
<artifactId>java-diff-utils-parent</artifactId>
|
||||
<version>4.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>java-diff-utils-jgit</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<description>This is an extension of java-diff-utils using jgit to use its implementation of
|
||||
some difference algorithms.</description>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<type>jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jgit</groupId>
|
||||
<artifactId>org.eclipse.jgit</artifactId>
|
||||
<version>4.4.1.201607150455-r</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.googlecode.javaewah</groupId>
|
||||
<artifactId>JavaEWAH</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.jcraft</groupId>
|
||||
<artifactId>jsch</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>java-diff-utils</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* 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 com.github.difflib.algorithm.jgit;
|
||||
|
||||
import com.github.difflib.algorithm.Change;
|
||||
import com.github.difflib.algorithm.DiffAlgorithmI;
|
||||
import com.github.difflib.algorithm.DiffAlgorithmListener;
|
||||
import com.github.difflib.patch.DeltaType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import org.eclipse.jgit.diff.Edit;
|
||||
import org.eclipse.jgit.diff.EditList;
|
||||
import org.eclipse.jgit.diff.Sequence;
|
||||
import org.eclipse.jgit.diff.SequenceComparator;
|
||||
|
||||
/**
|
||||
* HistorgramDiff using JGit - Library. This one is much more performant than the orginal Myers
|
||||
* implementation.
|
||||
*
|
||||
* @author toben
|
||||
*/
|
||||
public class HistogramDiff<T> implements DiffAlgorithmI<T> {
|
||||
|
||||
@Override
|
||||
public List<Change> computeDiff(List<T> source, List<T> target, DiffAlgorithmListener progress) {
|
||||
Objects.requireNonNull(source, "source list must not be null");
|
||||
Objects.requireNonNull(target, "target list must not be null");
|
||||
if (progress != null) {
|
||||
progress.diffStart();
|
||||
}
|
||||
EditList diffList = new EditList();
|
||||
diffList.addAll(new org.eclipse.jgit.diff.HistogramDiff().diff(new DataListComparator<>(progress), new DataList<>(source), new DataList<>(target)));
|
||||
List<Change> patch = new ArrayList<>();
|
||||
for (Edit edit : diffList) {
|
||||
DeltaType type = DeltaType.EQUAL;
|
||||
switch (edit.getType()) {
|
||||
case DELETE:
|
||||
type = DeltaType.DELETE;
|
||||
break;
|
||||
case INSERT:
|
||||
type = DeltaType.INSERT;
|
||||
break;
|
||||
case REPLACE:
|
||||
type = DeltaType.CHANGE;
|
||||
break;
|
||||
}
|
||||
patch.add(new Change(type, edit.getBeginA(), edit.getEndA(), edit.getBeginB(), edit.getEndB()));
|
||||
}
|
||||
if (progress != null) {
|
||||
progress.diffEnd();
|
||||
}
|
||||
return patch;
|
||||
}
|
||||
}
|
||||
|
||||
class DataListComparator<T> extends SequenceComparator<DataList<T>> {
|
||||
|
||||
private final DiffAlgorithmListener progress;
|
||||
|
||||
public DataListComparator(DiffAlgorithmListener progress) {
|
||||
this.progress = progress;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(DataList<T> original, int orgIdx, DataList<T> revised, int revIdx) {
|
||||
if (progress != null) {
|
||||
progress.diffStep(orgIdx + revIdx, original.size() + revised.size());
|
||||
}
|
||||
return original.data.get(orgIdx).equals(revised.data.get(revIdx));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hash(DataList<T> s, int i) {
|
||||
return s.data.get(i).hashCode();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class DataList<T> extends Sequence {
|
||||
|
||||
final List<T> data;
|
||||
|
||||
public DataList(List<T> data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return data.size();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* 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 com.github.difflib.algorithm.jgit;
|
||||
|
||||
import com.github.difflib.algorithm.DiffAlgorithmListener;
|
||||
import com.github.difflib.patch.Patch;
|
||||
import com.github.difflib.patch.PatchFailedException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author toben
|
||||
*/
|
||||
public class HistogramDiffTest {
|
||||
|
||||
public HistogramDiffTest() {
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpClass() {
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void tearDownClass() {
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of diff method, of class HistogramDiff.
|
||||
*/
|
||||
@Test
|
||||
public void testDiff() throws 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 = Patch.generate(orgList, revList, new HistogramDiff().computeDiff(orgList, revList, null));
|
||||
System.out.println(patch);
|
||||
assertNotNull(patch);
|
||||
assertEquals(3, patch.getDeltas().size());
|
||||
assertEquals("Patch{deltas=[[DeleteDelta, position: 0, lines: [A, B]], [DeleteDelta, position: 3, lines: [A, B]], [InsertDelta, position: 7, lines: [B, A, C]]]}", patch.toString());
|
||||
|
||||
List<String> patched = patch.applyTo(orgList);
|
||||
assertEquals(revList, patched);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDiffWithListener() throws PatchFailedException {
|
||||
List<String> orgList = Arrays.asList("A", "B", "C", "A", "B", "B", "A");
|
||||
List<String> revList = Arrays.asList("C", "B", "A", "B", "A", "C");
|
||||
|
||||
List<String> logdata = new ArrayList<>();
|
||||
final Patch<String> patch = Patch.generate(orgList, revList, new HistogramDiff().computeDiff(orgList, revList, new DiffAlgorithmListener() {
|
||||
@Override
|
||||
public void diffStart() {
|
||||
logdata.add("start");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void diffStep(int value, int max) {
|
||||
logdata.add(value + " - " + max);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void diffEnd() {
|
||||
logdata.add("end");
|
||||
}
|
||||
}));
|
||||
System.out.println(patch);
|
||||
assertNotNull(patch);
|
||||
assertEquals(3, patch.getDeltas().size());
|
||||
assertEquals("Patch{deltas=[[DeleteDelta, position: 0, lines: [A, B]], [DeleteDelta, position: 3, lines: [A, B]], [InsertDelta, position: 7, lines: [B, A, C]]]}", patch.toString());
|
||||
|
||||
List<String> patched = patch.applyTo(orgList);
|
||||
assertEquals(revList, patched);
|
||||
|
||||
System.out.println(logdata);
|
||||
assertEquals(17, logdata.size());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* 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 com.github.difflib.algorithm.jgit;
|
||||
|
||||
import com.github.difflib.algorithm.DiffAlgorithmListener;
|
||||
import com.github.difflib.patch.Patch;
|
||||
import com.github.difflib.patch.PatchFailedException;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import java.util.zip.ZipFile;
|
||||
import org.junit.After;
|
||||
import org.junit.AfterClass;
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author toben
|
||||
*/
|
||||
public class LRHistogramDiffTest {
|
||||
|
||||
public LRHistogramDiffTest() {
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpClass() {
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void tearDownClass() {
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPossibleDiffHangOnLargeDatasetDnaumenkoIssue26() throws IOException, PatchFailedException {
|
||||
ZipFile zip = new ZipFile("target/test-classes/mocks/large_dataset1.zip");
|
||||
List<String> original = readStringListFromInputStream(zip.getInputStream(zip.getEntry("ta")));
|
||||
List<String> revised = readStringListFromInputStream(zip.getInputStream(zip.getEntry("tb")));
|
||||
|
||||
List<String> logdata = new ArrayList<>();
|
||||
Patch<String> patch = Patch.generate(original, revised, new HistogramDiff().computeDiff(original, revised, new DiffAlgorithmListener() {
|
||||
@Override
|
||||
public void diffStart() {
|
||||
logdata.add("start");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void diffStep(int value, int max) {
|
||||
logdata.add(value + " - " + max);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void diffEnd() {
|
||||
logdata.add("end");
|
||||
}
|
||||
}));
|
||||
|
||||
assertEquals(34, patch.getDeltas().size());
|
||||
|
||||
List<String> created = patch.applyTo(original);
|
||||
assertArrayEquals(revised.toArray(), created.toArray());
|
||||
|
||||
assertEquals(246579, logdata.size());
|
||||
}
|
||||
|
||||
public static List<String> readStringListFromInputStream(InputStream is) throws IOException {
|
||||
try (BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader(is, Charset.forName(StandardCharsets.UTF_8.name())))) {
|
||||
|
||||
return reader.lines().collect(toList());
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
java-diff-utils-jgit/src/test/resources/mocks/large_dataset1.zip
Normal file
BIN
java-diff-utils-jgit/src/test/resources/mocks/large_dataset1.zip
Normal file
Binary file not shown.
Reference in New Issue
Block a user