mirror of
https://github.com/java-diff-utils/java-diff-utils.git
synced 2026-03-13 10:11:17 +08:00
Compare commits
84 Commits
java-diff-
...
java-diff-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d5f7ffca5c | ||
|
|
f194a871b1 | ||
|
|
ab9908f3bc | ||
|
|
8c7bb30b25 | ||
|
|
6c617ff949 | ||
|
|
0d9f2ce62d | ||
|
|
ce4007b124 | ||
|
|
6e4e3910c1 | ||
|
|
23a9c523c6 | ||
|
|
7d17c6088a | ||
|
|
17eced9367 | ||
|
|
c534ebae98 | ||
|
|
156f4f2986 | ||
|
|
c5b88e02db | ||
|
|
f3ff104a9c | ||
|
|
a24ceb930d | ||
|
|
e82408e7a8 | ||
|
|
93a5255007 | ||
|
|
73263b41cf | ||
|
|
a46d44643f | ||
|
|
fb3a8427bc | ||
|
|
5ab1882df8 | ||
|
|
865a464906 | ||
|
|
bb79a9b4fe | ||
|
|
4a5a39cf96 | ||
|
|
a40c396678 | ||
|
|
a3663002bb | ||
|
|
69cb8c520d | ||
|
|
0c75b43d88 | ||
|
|
5cc9625275 | ||
|
|
e520ee2f20 | ||
|
|
de227395cd | ||
|
|
ddd66e4554 | ||
|
|
4700647351 | ||
|
|
4727557814 | ||
|
|
630eed340b | ||
|
|
a018e9c432 | ||
|
|
d30d9ca23a | ||
|
|
7d620c825c | ||
|
|
16cd9c6484 | ||
|
|
30875cf6db | ||
|
|
a34c185a44 | ||
|
|
a8d968cc1d | ||
|
|
89f2659dd7 | ||
|
|
9704b62970 | ||
|
|
ecd834f3f5 | ||
|
|
8c6679e295 | ||
|
|
4c1a0bc072 | ||
|
|
fd64d15ab0 | ||
|
|
13f2f5ede1 | ||
|
|
1c3a2b598e | ||
|
|
4719139448 | ||
|
|
b5eb632a4d | ||
|
|
6321d5327c | ||
|
|
a4bb85bab1 | ||
|
|
535ecf3e2a | ||
|
|
61a21cbca9 | ||
|
|
4a83032d7e | ||
|
|
8c86e0f8d7 | ||
|
|
983ec680f7 | ||
|
|
05b5d80d48 | ||
|
|
d2355a8435 | ||
|
|
55e4867e88 | ||
|
|
253a94becb | ||
|
|
a523ba3a14 | ||
|
|
361c27d5e7 | ||
|
|
c917f77bbf | ||
|
|
4caf63c193 | ||
|
|
c0a1a3777c | ||
|
|
2787a2db6c | ||
|
|
e8c015a2ec | ||
|
|
765dc29386 | ||
|
|
a312ec14ea | ||
|
|
3443d55a19 | ||
|
|
b41e2d5b5a | ||
|
|
47c6e9b417 | ||
|
|
2d116d8c54 | ||
|
|
de2f19497a | ||
|
|
5dd05c480d | ||
|
|
fc1e247de2 | ||
|
|
ab05a8bdb4 | ||
|
|
5fe7e58f76 | ||
|
|
785c368f01 | ||
|
|
c9a2c9e7f0 |
24
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
24
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Create a report to help us improve
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Describe the bug**
|
||||||
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
|
**To Reproduce**
|
||||||
|
Steps to reproduce the behavior:
|
||||||
|
1. Example data
|
||||||
|
2. simple programm snippet
|
||||||
|
3. See error
|
||||||
|
|
||||||
|
**Expected behavior**
|
||||||
|
A clear and concise description of what you expected to happen.
|
||||||
|
|
||||||
|
**System**
|
||||||
|
- Java version
|
||||||
|
- Version [e.g. 22]
|
||||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -1,2 +1,4 @@
|
|||||||
/target/
|
.idea/
|
||||||
/nbproject/
|
build/
|
||||||
|
nbproject/
|
||||||
|
target/
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
language: java
|
language: java
|
||||||
jdk:
|
jdk:
|
||||||
- oraclejdk8
|
- openjdk8
|
||||||
|
- openjdk11
|
||||||
|
|
||||||
after_success:
|
after_success:
|
||||||
- mvn clean
|
- mvn clean
|
||||||
|
|||||||
85
CHANGELOG.md
Normal file
85
CHANGELOG.md
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
|
This project uses a custom versioning scheme (and not [Semantic Versioning](https://semver.org/spec/v2.0.0.html)).
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
* Exchange `0 += 1` for `0 = 1` in UnifiedDiffUtils
|
||||||
|
* preview of new Unified Diff Reader / Writer. This is not yet feature complete but passes the tests of the old version.
|
||||||
|
* feel free to issue some change requests for the api.
|
||||||
|
* introduces lineNormalizer extension point to e.g. change html code encoding. (issue #41)
|
||||||
|
|
||||||
|
## [4.0] – 2019-01-09
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
* moved to organisation **java-diff-utils**
|
||||||
|
* changed groupid to **io.github.java-diff-utils** and artifact id to **java-diff-utils**
|
||||||
|
|
||||||
|
## [3.0] – 2018-10-18
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
* Introduced a process listener to diff algorithms. For long running
|
||||||
|
diffs one could implement some progress information.
|
||||||
|
* automatic module name for JDK 9 and higher usage
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
* changed generation of inline diffes, if there are different linefeeds within one diff, then these are excluded from the diff block.
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
* Due to licensing issues Delta.java and DiffAlgorithm.java were removed.
|
||||||
|
|
||||||
|
## [2.2] – 2017-11-09
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
* released at maven central
|
||||||
|
* included checkstyle source code conventions
|
||||||
|
* allow configurable splitting of lines to define the blocks to compare (words, characters, phrases).
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
* groupid changed to **com.github.wumpz**, due to maven central releasing
|
||||||
|
|
||||||
|
## [2.0] – 2017-08-14
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
* support for inline merge
|
||||||
|
* integrated JGit (Eclipse Licensed) to provide HistogramDiff to gain speed for large datasets
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
* switch to maven and removed other artifacts
|
||||||
|
* changed groupid to **com.github.java-diff-utils** due to different forks at github
|
||||||
|
* updated maven plugins
|
||||||
|
* JDK 1.8 compatibility, sorry if you have to stick with older versions
|
||||||
|
* restructured packages heavily
|
||||||
|
* changed API
|
||||||
|
* changed Algorithm to provide only cursor positions
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
* removed all kinds of helper classes in favour of new JDK 8 function classes like Predicate
|
||||||
|
|
||||||
|
## 1.2
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
* JDK 1.5 compatibility
|
||||||
|
* Ant build script
|
||||||
|
* Generate output in unified diff format (thanks for Bill James)
|
||||||
|
|
||||||
|
[Unreleased]: https://github.com/java-diff-utils/java-diff-utils/compare/java-diff-utils-4.0...HEAD
|
||||||
|
[4.0]: https://github.com/java-diff-utils/java-diff-utils/compare/diff-utils-3.0...java-diff-utils-4.0
|
||||||
|
[3.0]: https://github.com/java-diff-utils/java-diff-utils/compare/diff-utils-2.2...diff-utils-3.0
|
||||||
|
[2.2]: https://github.com/java-diff-utils/java-diff-utils/compare/diff-utils-2.0...diff-utils-2.2
|
||||||
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
### Expected Behavior
|
|
||||||
|
|
||||||
|
|
||||||
### Actual Behavior
|
|
||||||
|
|
||||||
|
|
||||||
### Steps to Reproduce the Problem
|
|
||||||
|
|
||||||
1.
|
|
||||||
1.
|
|
||||||
1.
|
|
||||||
|
|
||||||
### Specifications
|
|
||||||
|
|
||||||
- Version:
|
|
||||||
- Platform:
|
|
||||||
- Subsystem:
|
|
||||||
108
README.md
108
README.md
@@ -1,20 +1,22 @@
|
|||||||
# java-diff-utils
|
# java-diff-utils
|
||||||
|
|
||||||
## Status ##
|
## Status
|
||||||
[](https://travis-ci.org/java-diff-utils/java-diff-utils) [](https://www.codacy.com/app/wumpz/java-diff-utils?utm_source=github.com&utm_medium=referral&utm_content=java-diff-utils/java-diff-utils&utm_campaign=Badge_Grade)
|
|
||||||
[](http://maven-badges.herokuapp.com/maven-central/com.github.wumpz/diffutils)
|
|
||||||
|
|
||||||
|
[](https://travis-ci.org/java-diff-utils/java-diff-utils)
|
||||||
|
[](https://www.codacy.com/app/wumpz/java-diff-utils?utm_source=github.com&utm_medium=referral&utm_content=java-diff-utils/java-diff-utils&utm_campaign=Badge_Grade)
|
||||||
|
[](http://maven-badges.herokuapp.com/maven-central/io.github.java-diff-utils/java-diff-utils)
|
||||||
|
|
||||||
|
## Intro
|
||||||
|
|
||||||
## Intro ##
|
|
||||||
Diff Utils library is an OpenSource library for performing the comparison operations between texts: computing diffs, applying patches, generating unified diffs or parsing them, generating diff output for easy future displaying (like side-by-side view) and so on.
|
Diff Utils library is an OpenSource library for performing the comparison operations between texts: computing diffs, applying patches, generating unified diffs or parsing them, generating diff output for easy future displaying (like side-by-side view) and so on.
|
||||||
|
|
||||||
Main reason to build this library was the lack of easy-to-use libraries with all the usual stuff you need while working with diff files. Originally it was inspired by JRCS library and it's nice design of diff module.
|
Main reason to build this library was the lack of easy-to-use libraries with all the usual stuff you need while working with diff files. Originally it was inspired by JRCS library and it's nice design of diff module.
|
||||||
|
|
||||||
**This is originally a fork of java-diff-utils from Google Code Archive.**
|
**This is originally a fork of java-diff-utils from Google Code Archive.**
|
||||||
|
|
||||||
## Examples ##
|
## Examples
|
||||||
|
|
||||||
Look [here](https://github.com/wumpz/java-diff-utils/wiki) to find more helpful informations and examples.
|
Look [here](https://github.com/wumpz/java-diff-utils/wiki) to find more helpful informations and examples.
|
||||||
|
|
||||||
These two outputs are generated using this java-diff-utils. The source code can also be found at the *Examples* page:
|
These two outputs are generated using this java-diff-utils. The source code can also be found at the *Examples* page:
|
||||||
|
|
||||||
@@ -22,7 +24,6 @@ These two outputs are generated using this java-diff-utils. The source code can
|
|||||||
|
|
||||||
This is a test ~senctence~**for diffutils**.
|
This is a test ~senctence~**for diffutils**.
|
||||||
|
|
||||||
|
|
||||||
**Producing a side by side view of computed differences.**
|
**Producing a side by side view of computed differences.**
|
||||||
|
|
||||||
|original|new|
|
|original|new|
|
||||||
@@ -31,102 +32,61 @@ This is a test ~senctence~**for diffutils**.
|
|||||||
|This is the second line.|This is the second line.|
|
|This is the second line.|This is the second line.|
|
||||||
|~And here is the finish.~||
|
|~And here is the finish.~||
|
||||||
|
|
||||||
|
## Main Features
|
||||||
|
|
||||||
## Main Features ##
|
* computing the difference between two texts.
|
||||||
|
* capable to hand more than plain ascii. Arrays or List of any type that implements hashCode() and equals() correctly can be subject to differencing using this library
|
||||||
|
* patch and unpatch the text with the given patch
|
||||||
|
* parsing the unified diff format
|
||||||
|
* producing human-readable differences
|
||||||
|
* inline difference construction
|
||||||
|
* Algorithms:
|
||||||
|
* Myer
|
||||||
|
* HistogramDiff using JGit Library
|
||||||
|
|
||||||
* computing the difference between two texts.
|
### Algorithms
|
||||||
* capable to hand more than plain ascci. Arrays or List of any type that implements hashCode() and equals() correctly can be subject to differencing using this library
|
|
||||||
* patch and unpatch the text with the given patch
|
|
||||||
* parsing the unified diff format
|
|
||||||
* producing human-readable differences
|
|
||||||
* inline difference construction
|
|
||||||
* Algorithms:
|
|
||||||
* Myer
|
|
||||||
* HistogramDiff using JGit Library
|
|
||||||
|
|
||||||
### Algoritms ###
|
|
||||||
|
|
||||||
* Myer's diff
|
* Myer's diff
|
||||||
* HistogramDiff
|
* HistogramDiff
|
||||||
|
|
||||||
But it can easily replaced by any other which is better for handing your texts. I have plan to add implementation of some in future.
|
But it can easily replaced by any other which is better for handing your texts. I have plan to add implementation of some in future.
|
||||||
|
|
||||||
### Changelog ###
|
|
||||||
* Version 4.0-SNAPSHOT
|
|
||||||
* moved to organisation **java-diff-utils**
|
|
||||||
* changed groupid to **io.github.java-diff-utils** and artifact id to **java-diff-utils**
|
|
||||||
* Version 3.0
|
|
||||||
* changed generation of inline diffes, if there are different linefeeds within one diff, then these are excluded
|
|
||||||
from the diff block.
|
|
||||||
* Due to licensing issues Delta.java and DiffAlgorithm.java were removed.
|
|
||||||
* Version 2.3-SNAPSHOT
|
|
||||||
* Introduced a process listener to diff algorithms. For long running
|
|
||||||
diffs one could implement some progress information.
|
|
||||||
* automatic module name for JDK 9 and higher usage
|
|
||||||
* Version 2.2
|
|
||||||
* released at maven central
|
|
||||||
* included checkstyle source code conventions
|
|
||||||
* groupid changed to **com.github.wumpz**, due to maven central releasing
|
|
||||||
* allow configurable splitting of lines to define the blocks to compare (words, characters, phrases).
|
|
||||||
* Version 2.0
|
|
||||||
* switch to maven and removed other artifacts
|
|
||||||
* changed groupid to **com.github.java-diff-utils** due to different forks at github
|
|
||||||
* updated maven plugins
|
|
||||||
* JDK 1.8 compatibility, sorry if you have to stick with older versions
|
|
||||||
* support for inline merge
|
|
||||||
* restructured packages heavily
|
|
||||||
* changed API
|
|
||||||
* changed Algorithm to provide only cursor positions
|
|
||||||
* integrated JGit (Eclipse Licensed) to provide HistogramDiff to gain speed for large datasets
|
|
||||||
* removed all kinds of helper classes in favour of new JDK 8 function classes like Predicate
|
|
||||||
* Version 1.2
|
|
||||||
* JDK 1.5 compatibility
|
|
||||||
* Ant build script
|
|
||||||
* Generate output in unified diff format (thanks for Bill James)
|
|
||||||
|
|
||||||
## Source Code conventions
|
## Source Code conventions
|
||||||
|
|
||||||
Recently a checkstyle process was integrated into the build process. java-diff-utils follows the sun java format convention. There are no TABs allowed. Use spaces.
|
Recently a checkstyle process was integrated into the build process. java-diff-utils follows the sun java format convention. There are no TABs allowed. Use spaces.
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public static <T> Patch<T> diff(List<T> original, List<T> revised,
|
public static <T> Patch<T> diff(List<T> original, List<T> revised,
|
||||||
BiPredicate<T, T> equalizer) throws DiffException {
|
BiPredicate<T, T> equalizer) throws DiffException {
|
||||||
if (equalizer != null) {
|
if (equalizer != null) {
|
||||||
return DiffUtils.diff(original, revised,
|
return DiffUtils.diff(original, revised,
|
||||||
new MyersDiff<>(equalizer));
|
new MyersDiff<>(equalizer));
|
||||||
}
|
}
|
||||||
return DiffUtils.diff(original, revised, new MyersDiff<>());
|
return DiffUtils.diff(original, revised, new MyersDiff<>());
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
This is a valid piece of source code:
|
This is a valid piece of source code:
|
||||||
|
|
||||||
* blocks without braces are not allowed
|
* blocks without braces are not allowed
|
||||||
* after control statements (if, while, for) a whitespace is expected
|
* after control statements (if, while, for) a whitespace is expected
|
||||||
* the opening brace should be in the same line as the control statement
|
* the opening brace should be in the same line as the control statement
|
||||||
|
|
||||||
### To Install ###
|
### To Install
|
||||||
|
|
||||||
Just add the code below to your maven dependencies:
|
Just add the code below to your maven dependencies:
|
||||||
```
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.github.wumpz</groupId>
|
|
||||||
<artifactId>diffutils</artifactId>
|
|
||||||
<version>3.0</version>
|
|
||||||
</dependency>
|
|
||||||
```
|
|
||||||
|
|
||||||
Attention. We changed groupid and artifactid. Starting with version 4 you have to use:
|
```xml
|
||||||
|
|
||||||
```
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.github.java-diff-utils</groupId>
|
<groupId>io.github.java-diff-utils</groupId>
|
||||||
<artifactId>java-diff-utils</artifactId>
|
<artifactId>java-diff-utils</artifactId>
|
||||||
<version>4.0-SNAPSHOT</version>
|
<version>4.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
```
|
```
|
||||||
|
|
||||||
or using gradle:
|
or using gradle:
|
||||||
```
|
|
||||||
// https://mvnrepository.com/artifact/com.github.wumpz/diffutils
|
```groovy
|
||||||
compile group: 'com.github.wumpz', name: 'diffutils', version: '2.2'
|
// https://mvnrepository.com/artifact/io.github.java-diff-utils/java-diff-utils
|
||||||
|
implementation "io.github.java-diff-utils:java-diff-utils:4.0"
|
||||||
```
|
```
|
||||||
|
|||||||
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>
|
||||||
59
java-diff-utils-jgit/pom.xml
Normal file
59
java-diff-utils-jgit/pom.xml
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
<?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.4</version>
|
||||||
|
</parent>
|
||||||
|
<artifactId>java-diff-utils-jgit</artifactId>
|
||||||
|
<name>java-diff-utils-jgit</name>
|
||||||
|
<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>
|
||||||
@@ -18,7 +18,6 @@ package com.github.difflib.algorithm.jgit;
|
|||||||
import com.github.difflib.algorithm.Change;
|
import com.github.difflib.algorithm.Change;
|
||||||
import com.github.difflib.algorithm.DiffAlgorithmI;
|
import com.github.difflib.algorithm.DiffAlgorithmI;
|
||||||
import com.github.difflib.algorithm.DiffAlgorithmListener;
|
import com.github.difflib.algorithm.DiffAlgorithmListener;
|
||||||
import com.github.difflib.algorithm.DiffException;
|
|
||||||
import com.github.difflib.patch.DeltaType;
|
import com.github.difflib.patch.DeltaType;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -37,7 +36,7 @@ import org.eclipse.jgit.diff.SequenceComparator;
|
|||||||
public class HistogramDiff<T> implements DiffAlgorithmI<T> {
|
public class HistogramDiff<T> implements DiffAlgorithmI<T> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Change> computeDiff(List<T> source, List<T> target, DiffAlgorithmListener progress) throws DiffException {
|
public List<Change> computeDiff(List<T> source, List<T> target, DiffAlgorithmListener progress) {
|
||||||
Objects.requireNonNull(source, "source list must not be null");
|
Objects.requireNonNull(source, "source list must not be null");
|
||||||
Objects.requireNonNull(target, "target list must not be null");
|
Objects.requireNonNull(target, "target list must not be null");
|
||||||
if (progress != null) {
|
if (progress != null) {
|
||||||
@@ -16,7 +16,6 @@
|
|||||||
package com.github.difflib.algorithm.jgit;
|
package com.github.difflib.algorithm.jgit;
|
||||||
|
|
||||||
import com.github.difflib.algorithm.DiffAlgorithmListener;
|
import com.github.difflib.algorithm.DiffAlgorithmListener;
|
||||||
import com.github.difflib.algorithm.DiffException;
|
|
||||||
import com.github.difflib.patch.Patch;
|
import com.github.difflib.patch.Patch;
|
||||||
import com.github.difflib.patch.PatchFailedException;
|
import com.github.difflib.patch.PatchFailedException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -58,7 +57,7 @@ public class HistogramDiffTest {
|
|||||||
* Test of diff method, of class HistogramDiff.
|
* Test of diff method, of class HistogramDiff.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testDiff() throws DiffException, PatchFailedException {
|
public void testDiff() throws PatchFailedException {
|
||||||
List<String> orgList = Arrays.asList("A", "B", "C", "A", "B", "B", "A");
|
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> revList = Arrays.asList("C", "B", "A", "B", "A", "C");
|
||||||
final Patch<String> patch = Patch.generate(orgList, revList, new HistogramDiff().computeDiff(orgList, revList, null));
|
final Patch<String> patch = Patch.generate(orgList, revList, new HistogramDiff().computeDiff(orgList, revList, null));
|
||||||
@@ -72,7 +71,7 @@ public class HistogramDiffTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDiffWithListener() throws DiffException, PatchFailedException {
|
public void testDiffWithListener() throws PatchFailedException {
|
||||||
List<String> orgList = Arrays.asList("A", "B", "C", "A", "B", "B", "A");
|
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> revList = Arrays.asList("C", "B", "A", "B", "A", "C");
|
||||||
|
|
||||||
@@ -15,15 +15,18 @@
|
|||||||
*/
|
*/
|
||||||
package com.github.difflib.algorithm.jgit;
|
package com.github.difflib.algorithm.jgit;
|
||||||
|
|
||||||
import static com.github.difflib.DiffUtilsTest.readStringListFromInputStream;
|
|
||||||
import com.github.difflib.TestConstants;
|
|
||||||
import com.github.difflib.algorithm.DiffAlgorithmListener;
|
import com.github.difflib.algorithm.DiffAlgorithmListener;
|
||||||
import com.github.difflib.algorithm.DiffException;
|
|
||||||
import com.github.difflib.patch.Patch;
|
import com.github.difflib.patch.Patch;
|
||||||
import com.github.difflib.patch.PatchFailedException;
|
import com.github.difflib.patch.PatchFailedException;
|
||||||
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
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.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import static java.util.stream.Collectors.toList;
|
||||||
import java.util.zip.ZipFile;
|
import java.util.zip.ZipFile;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
@@ -58,8 +61,8 @@ public class LRHistogramDiffTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPossibleDiffHangOnLargeDatasetDnaumenkoIssue26() throws IOException, DiffException, PatchFailedException {
|
public void testPossibleDiffHangOnLargeDatasetDnaumenkoIssue26() throws IOException, PatchFailedException {
|
||||||
ZipFile zip = new ZipFile(TestConstants.MOCK_FOLDER + "/large_dataset1.zip");
|
ZipFile zip = new ZipFile("target/test-classes/mocks/large_dataset1.zip");
|
||||||
List<String> original = readStringListFromInputStream(zip.getInputStream(zip.getEntry("ta")));
|
List<String> original = readStringListFromInputStream(zip.getInputStream(zip.getEntry("ta")));
|
||||||
List<String> revised = readStringListFromInputStream(zip.getInputStream(zip.getEntry("tb")));
|
List<String> revised = readStringListFromInputStream(zip.getInputStream(zip.getEntry("tb")));
|
||||||
|
|
||||||
@@ -86,7 +89,14 @@ public class LRHistogramDiffTest {
|
|||||||
List<String> created = patch.applyTo(original);
|
List<String> created = patch.applyTo(original);
|
||||||
assertArrayEquals(revised.toArray(), created.toArray());
|
assertArrayEquals(revised.toArray(), created.toArray());
|
||||||
|
|
||||||
assertEquals(50, logdata.size());
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
60
java-diff-utils/pom.xml
Normal file
60
java-diff-utils/pom.xml
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
<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/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>io.github.java-diff-utils</groupId>
|
||||||
|
<artifactId>java-diff-utils</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<name>java-diff-utils</name>
|
||||||
|
<parent>
|
||||||
|
<groupId>io.github.java-diff-utils</groupId>
|
||||||
|
<artifactId>java-diff-utils-parent</artifactId>
|
||||||
|
<version>4.4</version>
|
||||||
|
</parent>
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.12</version>
|
||||||
|
<type>jar</type>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.assertj</groupId>
|
||||||
|
<artifactId>assertj-core</artifactId>
|
||||||
|
<version>3.11.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.6.1</version>
|
||||||
|
<configuration>
|
||||||
|
<source>1.8</source>
|
||||||
|
<target>1.8</target>
|
||||||
|
<encoding>UTF-8</encoding>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<version>3.0.2</version>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
|
||||||
|
<manifestEntries>
|
||||||
|
<!-- identical to OSGI name -->
|
||||||
|
<Automatic-Module-Name>io.github.java-diff-utils</Automatic-Module-Name>
|
||||||
|
</manifestEntries>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
|
|
||||||
@@ -28,7 +28,6 @@ import java.util.Collections;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.function.BiPredicate;
|
import java.util.function.BiPredicate;
|
||||||
import static java.util.stream.Collectors.joining;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements the difference and patching engine
|
* Implements the difference and patching engine
|
||||||
@@ -143,7 +142,7 @@ public final class DiffUtils {
|
|||||||
if (lines.isEmpty()) {
|
if (lines.isEmpty()) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
return Collections.singletonList(lines.stream().collect(joining(delimiter)));
|
return Collections.singletonList(String.join(delimiter, lines));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -83,10 +83,10 @@ public final class UnifiedDiffUtils {
|
|||||||
new_ln = m.group(3) == null ? 1 : Integer.parseInt(m.group(3));
|
new_ln = m.group(3) == null ? 1 : Integer.parseInt(m.group(3));
|
||||||
|
|
||||||
if (old_ln == 0) {
|
if (old_ln == 0) {
|
||||||
old_ln += 1;
|
old_ln = 1;
|
||||||
}
|
}
|
||||||
if (new_ln == 0) {
|
if (new_ln == 0) {
|
||||||
new_ln += 1;
|
new_ln = 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (line.length() > 0) {
|
if (line.length() > 0) {
|
||||||
@@ -18,8 +18,8 @@ package com.github.difflib.algorithm;
|
|||||||
/**
|
/**
|
||||||
* Thrown whenever the differencing engine cannot produce the differences between two revisions of ta text.
|
* Thrown whenever the differencing engine cannot produce the differences between two revisions of ta text.
|
||||||
*
|
*
|
||||||
* @see MyersDiff
|
* @see com.github.difflib.algorithm.myers.MyersDiff
|
||||||
* @see difflib.DiffAlgorithm
|
* @see DiffAlgorithmI
|
||||||
*/
|
*/
|
||||||
public class DifferentiationFailedException extends DiffException {
|
public class DifferentiationFailedException extends DiffException {
|
||||||
|
|
||||||
@@ -138,7 +138,7 @@ public final class MyersDiff<T> implements DiffAlgorithmI<T> {
|
|||||||
/**
|
/**
|
||||||
* Constructs a {@link Patch} from a difference path.
|
* Constructs a {@link Patch} from a difference path.
|
||||||
*
|
*
|
||||||
* @param path The path.
|
* @param actualPath The path.
|
||||||
* @param orig The original sequence.
|
* @param orig The original sequence.
|
||||||
* @param rev The revised sequence.
|
* @param rev The revised sequence.
|
||||||
* @return A {@link Patch} script corresponding to the path.
|
* @return A {@link Patch} script corresponding to the path.
|
||||||
@@ -19,10 +19,6 @@ package com.github.difflib.algorithm.myers;
|
|||||||
* A node in a diffpath.
|
* A node in a diffpath.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:juanco@suigeneris.org">Juanco Anez</a>
|
* @author <a href="mailto:juanco@suigeneris.org">Juanco Anez</a>
|
||||||
*
|
|
||||||
* @see DiffNode
|
|
||||||
* @see Snake
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public final class PathNode {
|
public final class PathNode {
|
||||||
|
|
||||||
@@ -78,10 +74,10 @@ public final class PathNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Skips sequences of {@link DiffNode DiffNodes} until a {@link Snake} or bootstrap node is found, or the end of the
|
* Skips sequences of {@link PathNode PathNodes} until a snake or bootstrap node is found, or the end of the
|
||||||
* path is reached.
|
* path is reached.
|
||||||
*
|
*
|
||||||
* @return The next first {@link Snake} or bootstrap node in the path, or <code>null</code> if none found.
|
* @return The next first {@link PathNode} or bootstrap node in the path, or <code>null</code> if none found.
|
||||||
*/
|
*/
|
||||||
public final PathNode previousSnake() {
|
public final PathNode previousSnake() {
|
||||||
if (isBootstrap()) {
|
if (isBootstrap()) {
|
||||||
@@ -102,9 +98,9 @@ public final class PathNode {
|
|||||||
PathNode node = this;
|
PathNode node = this;
|
||||||
while (node != null) {
|
while (node != null) {
|
||||||
buf.append("(");
|
buf.append("(");
|
||||||
buf.append(Integer.toString(node.i));
|
buf.append(node.i);
|
||||||
buf.append(",");
|
buf.append(",");
|
||||||
buf.append(Integer.toString(node.j));
|
buf.append(node.j);
|
||||||
buf.append(")");
|
buf.append(")");
|
||||||
node = node.prev;
|
node = node.prev;
|
||||||
}
|
}
|
||||||
@@ -22,7 +22,7 @@ import java.util.Objects;
|
|||||||
* Describes the change-delta between original and revised texts.
|
* Describes the change-delta between original and revised texts.
|
||||||
*
|
*
|
||||||
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
|
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
|
||||||
* @param T The type of the compared elements in the data 'lines'.
|
* @param <T> The type of the compared elements in the data 'lines'.
|
||||||
*/
|
*/
|
||||||
public final class ChangeDelta<T> extends AbstractDelta<T> {
|
public final class ChangeDelta<T> extends AbstractDelta<T> {
|
||||||
|
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.github.difflib.patch;
|
package com.github.difflib.patch;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@@ -23,13 +24,14 @@ import java.util.Objects;
|
|||||||
* Holds the information about the part of text involved in the diff process
|
* Holds the information about the part of text involved in the diff process
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Text is represented as <code>Object[]</code> because the diff engine is capable of handling more than plain ascci. In
|
* Text is represented as <code>Object[]</code> because the diff engine is capable of handling more
|
||||||
* fact, arrays or lists of any type that implements {@link java.lang.Object#hashCode hashCode()} and
|
* than plain ascci. In fact, arrays or lists of any type that implements
|
||||||
* {@link java.lang.Object#equals equals()} correctly can be subject to differencing using this library.
|
* {@link java.lang.Object#hashCode hashCode()} and {@link java.lang.Object#equals equals()}
|
||||||
|
* correctly can be subject to differencing using this library.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @author <a href="dm.naumenko@gmail.com>Dmitry Naumenko</a>
|
* @author <a href="dm.naumenko@gmail.com>Dmitry Naumenko</a>
|
||||||
* @param T The type of the compared elements in the 'lines'.
|
* @param <T> The type of the compared elements in the 'lines'.
|
||||||
*/
|
*/
|
||||||
public final class Chunk<T> {
|
public final class Chunk<T> {
|
||||||
|
|
||||||
@@ -44,7 +46,7 @@ public final class Chunk<T> {
|
|||||||
*/
|
*/
|
||||||
public Chunk(int position, List<T> lines) {
|
public Chunk(int position, List<T> lines) {
|
||||||
this.position = position;
|
this.position = position;
|
||||||
this.lines = lines;
|
this.lines = new ArrayList<>(lines);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -21,7 +21,7 @@ import java.util.List;
|
|||||||
* Describes the delete-delta between original and revised texts.
|
* Describes the delete-delta between original and revised texts.
|
||||||
*
|
*
|
||||||
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
|
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
|
||||||
* @param T The type of the compared elements in the 'lines'.
|
* @param <T> The type of the compared elements in the 'lines'.
|
||||||
*/
|
*/
|
||||||
public final class DeleteDelta<T> extends AbstractDelta<T> {
|
public final class DeleteDelta<T> extends AbstractDelta<T> {
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ import java.util.List;
|
|||||||
* Describes the add-delta between original and revised texts.
|
* Describes the add-delta between original and revised texts.
|
||||||
*
|
*
|
||||||
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
|
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
|
||||||
* @param T The type of the compared elements in the 'lines'.
|
* @param <T> The type of the compared elements in the 'lines'.
|
||||||
*/
|
*/
|
||||||
public final class InsertDelta<T> extends AbstractDelta<T> {
|
public final class InsertDelta<T> extends AbstractDelta<T> {
|
||||||
|
|
||||||
@@ -19,12 +19,9 @@ limitations under the License.
|
|||||||
*/
|
*/
|
||||||
package com.github.difflib.patch;
|
package com.github.difflib.patch;
|
||||||
|
|
||||||
import com.github.difflib.algorithm.Change;
|
|
||||||
import static com.github.difflib.patch.DeltaType.DELETE;
|
|
||||||
import static com.github.difflib.patch.DeltaType.INSERT;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import static java.util.Comparator.comparing;
|
import static java.util.Comparator.comparing;
|
||||||
|
import com.github.difflib.algorithm.Change;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ListIterator;
|
import java.util.ListIterator;
|
||||||
|
|
||||||
@@ -32,7 +29,7 @@ import java.util.ListIterator;
|
|||||||
* Describes the patch holding all deltas between the original and revised texts.
|
* Describes the patch holding all deltas between the original and revised texts.
|
||||||
*
|
*
|
||||||
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
|
* @author <a href="dm.naumenko@gmail.com">Dmitry Naumenko</a>
|
||||||
* @param T The type of the compared elements in the 'lines'.
|
* @param <T> The type of the compared elements in the 'lines'.
|
||||||
*/
|
*/
|
||||||
public final class Patch<T> {
|
public final class Patch<T> {
|
||||||
|
|
||||||
@@ -93,7 +90,7 @@ public final class Patch<T> {
|
|||||||
* @return the deltas
|
* @return the deltas
|
||||||
*/
|
*/
|
||||||
public List<AbstractDelta<T>> getDeltas() {
|
public List<AbstractDelta<T>> getDeltas() {
|
||||||
Collections.sort(deltas, comparing(d -> d.getSource().getPosition()));
|
deltas.sort(comparing(d -> d.getSource().getPosition()));
|
||||||
return deltas;
|
return deltas;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,6 +29,7 @@ import java.util.function.BiPredicate;
|
|||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
import static java.util.stream.Collectors.toList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class for generating DiffRows for side-by-sidy view. You can customize the way of generating. For example, show
|
* This class for generating DiffRows for side-by-sidy view. You can customize the way of generating. For example, show
|
||||||
@@ -42,13 +43,16 @@ import java.util.regex.Pattern;
|
|||||||
* ignoreWhiteSpaces(true).columnWidth(100).build();
|
* ignoreWhiteSpaces(true).columnWidth(100).build();
|
||||||
* </code>
|
* </code>
|
||||||
*/
|
*/
|
||||||
public class DiffRowGenerator {
|
public final class DiffRowGenerator {
|
||||||
|
|
||||||
public static final BiPredicate<String, String> DEFAULT_EQUALIZER = Object::equals;
|
public static final BiPredicate<String, String> DEFAULT_EQUALIZER = Object::equals;
|
||||||
|
|
||||||
public static final BiPredicate<String, String> IGNORE_WHITESPACE_EQUALIZER = (original, revised)
|
public static final BiPredicate<String, String> IGNORE_WHITESPACE_EQUALIZER = (original, revised)
|
||||||
-> adjustWhitespace(original).equals(adjustWhitespace(revised));
|
-> adjustWhitespace(original).equals(adjustWhitespace(revised));
|
||||||
|
|
||||||
|
public static final Function<String, String> LINE_NORMALIZER_FOR_HTML = StringUtils::normalize;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Splitting lines by character to achieve char by char diff checking.
|
* Splitting lines by character to achieve char by char diff checking.
|
||||||
*/
|
*/
|
||||||
@@ -60,6 +64,7 @@ public class DiffRowGenerator {
|
|||||||
return list;
|
return list;
|
||||||
};
|
};
|
||||||
public static final Pattern SPLIT_BY_WORD_PATTERN = Pattern.compile("\\s+|[,.\\[\\](){}/\\\\*+\\-#]");
|
public static final Pattern SPLIT_BY_WORD_PATTERN = Pattern.compile("\\s+|[,.\\[\\](){}/\\\\*+\\-#]");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Splitting lines by word to achieve word by word diff checking.
|
* Splitting lines by word to achieve word by word diff checking.
|
||||||
*/
|
*/
|
||||||
@@ -98,8 +103,7 @@ public class DiffRowGenerator {
|
|||||||
*
|
*
|
||||||
* @param startPosition the position from which tag should start. The counting start from a zero.
|
* @param startPosition the position from which tag should start. The counting start from a zero.
|
||||||
* @param endPosition the position before which tag should should be closed.
|
* @param endPosition the position before which tag should should be closed.
|
||||||
* @param tag the tag name without angle brackets, just a word
|
* @param tagGenerator the tag generator
|
||||||
* @param cssClass the optional css class
|
|
||||||
*/
|
*/
|
||||||
static void wrapInTag(List<String> sequence, int startPosition,
|
static void wrapInTag(List<String> sequence, int startPosition,
|
||||||
int endPosition, Function<Boolean, String> tagGenerator) {
|
int endPosition, Function<Boolean, String> tagGenerator) {
|
||||||
@@ -145,6 +149,7 @@ public class DiffRowGenerator {
|
|||||||
private final Function<Boolean, String> newTag;
|
private final Function<Boolean, String> newTag;
|
||||||
private final Function<Boolean, String> oldTag;
|
private final Function<Boolean, String> oldTag;
|
||||||
private final boolean reportLinesUnchanged;
|
private final boolean reportLinesUnchanged;
|
||||||
|
private final Function<String, String> lineNormalizer;
|
||||||
|
|
||||||
private final boolean showInlineDiffs;
|
private final boolean showInlineDiffs;
|
||||||
|
|
||||||
@@ -158,8 +163,10 @@ public class DiffRowGenerator {
|
|||||||
inlineDiffSplitter = builder.inlineDiffSplitter;
|
inlineDiffSplitter = builder.inlineDiffSplitter;
|
||||||
equalizer = ignoreWhiteSpaces ? IGNORE_WHITESPACE_EQUALIZER : DEFAULT_EQUALIZER;
|
equalizer = ignoreWhiteSpaces ? IGNORE_WHITESPACE_EQUALIZER : DEFAULT_EQUALIZER;
|
||||||
reportLinesUnchanged = builder.reportLinesUnchanged;
|
reportLinesUnchanged = builder.reportLinesUnchanged;
|
||||||
|
lineNormalizer = builder.lineNormalizer;
|
||||||
|
|
||||||
Objects.requireNonNull(inlineDiffSplitter);
|
Objects.requireNonNull(inlineDiffSplitter);
|
||||||
|
Objects.requireNonNull(lineNormalizer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -179,7 +186,6 @@ public class DiffRowGenerator {
|
|||||||
* for displaying side-by-side diff.
|
* for displaying side-by-side diff.
|
||||||
*
|
*
|
||||||
* @param original the original text
|
* @param original the original text
|
||||||
* @param revised the revised text
|
|
||||||
* @param patch the given patch
|
* @param patch the given patch
|
||||||
* @return the DiffRows between original and revised texts
|
* @return the DiffRows between original and revised texts
|
||||||
*/
|
*/
|
||||||
@@ -187,8 +193,7 @@ public class DiffRowGenerator {
|
|||||||
List<DiffRow> diffRows = new ArrayList<>();
|
List<DiffRow> diffRows = new ArrayList<>();
|
||||||
int endPos = 0;
|
int endPos = 0;
|
||||||
final List<AbstractDelta<String>> deltaList = patch.getDeltas();
|
final List<AbstractDelta<String>> deltaList = patch.getDeltas();
|
||||||
for (int i = 0; i < deltaList.size(); i++) {
|
for (AbstractDelta<String> delta : deltaList) {
|
||||||
AbstractDelta<String> delta = deltaList.get(i);
|
|
||||||
Chunk<String> orig = delta.getSource();
|
Chunk<String> orig = delta.getSource();
|
||||||
Chunk<String> rev = delta.getTarget();
|
Chunk<String> rev = delta.getTarget();
|
||||||
|
|
||||||
@@ -199,7 +204,7 @@ public class DiffRowGenerator {
|
|||||||
// Inserted DiffRow
|
// Inserted DiffRow
|
||||||
if (delta instanceof InsertDelta) {
|
if (delta instanceof InsertDelta) {
|
||||||
endPos = orig.last() + 1;
|
endPos = orig.last() + 1;
|
||||||
for (String line : (List<String>) rev.getLines()) {
|
for (String line : rev.getLines()) {
|
||||||
diffRows.add(buildDiffRow(Tag.INSERT, "", line));
|
diffRows.add(buildDiffRow(Tag.INSERT, "", line));
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
@@ -208,7 +213,7 @@ public class DiffRowGenerator {
|
|||||||
// Deleted DiffRow
|
// Deleted DiffRow
|
||||||
if (delta instanceof DeleteDelta) {
|
if (delta instanceof DeleteDelta) {
|
||||||
endPos = orig.last() + 1;
|
endPos = orig.last() + 1;
|
||||||
for (String line : (List<String>) orig.getLines()) {
|
for (String line : orig.getLines()) {
|
||||||
diffRows.add(buildDiffRow(Tag.DELETE, line, ""));
|
diffRows.add(buildDiffRow(Tag.DELETE, line, ""));
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
@@ -261,14 +266,22 @@ public class DiffRowGenerator {
|
|||||||
StringUtils.wrapText(newline, columnWidth));
|
StringUtils.wrapText(newline, columnWidth));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<String> normalizeLines(List<String> list) {
|
||||||
|
return reportLinesUnchanged
|
||||||
|
? list
|
||||||
|
: list.stream()
|
||||||
|
.map(lineNormalizer::apply)
|
||||||
|
.collect(toList());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add the inline diffs for given delta
|
* Add the inline diffs for given delta
|
||||||
*
|
*
|
||||||
* @param delta the given delta
|
* @param delta the given delta
|
||||||
*/
|
*/
|
||||||
private List<DiffRow> generateInlineDiffs(AbstractDelta<String> delta) throws DiffException {
|
private List<DiffRow> generateInlineDiffs(AbstractDelta<String> delta) throws DiffException {
|
||||||
List<String> orig = StringUtils.normalize(delta.getSource().getLines());
|
List<String> orig = normalizeLines(delta.getSource().getLines());
|
||||||
List<String> rev = StringUtils.normalize(delta.getTarget().getLines());
|
List<String> rev = normalizeLines(delta.getTarget().getLines());
|
||||||
List<String> origList;
|
List<String> origList;
|
||||||
List<String> revList;
|
List<String> revList;
|
||||||
String joinedOrig = String.join("\n", orig);
|
String joinedOrig = String.join("\n", orig);
|
||||||
@@ -337,9 +350,9 @@ public class DiffRowGenerator {
|
|||||||
|
|
||||||
private String preprocessLine(String line) {
|
private String preprocessLine(String line) {
|
||||||
if (columnWidth == 0) {
|
if (columnWidth == 0) {
|
||||||
return StringUtils.normalize(line);
|
return lineNormalizer.apply(line);
|
||||||
} else {
|
} else {
|
||||||
return StringUtils.wrapText(StringUtils.normalize(line), columnWidth);
|
return StringUtils.wrapText(lineNormalizer.apply(line), columnWidth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -361,6 +374,7 @@ public class DiffRowGenerator {
|
|||||||
private boolean mergeOriginalRevised = false;
|
private boolean mergeOriginalRevised = false;
|
||||||
private boolean reportLinesUnchanged = false;
|
private boolean reportLinesUnchanged = false;
|
||||||
private Function<String, List<String>> inlineDiffSplitter = SPLITTER_BY_CHARACTER;
|
private Function<String, List<String>> inlineDiffSplitter = SPLITTER_BY_CHARACTER;
|
||||||
|
private Function<String, String> lineNormalizer = LINE_NORMALIZER_FOR_HTML;
|
||||||
|
|
||||||
private Builder() {
|
private Builder() {
|
||||||
}
|
}
|
||||||
@@ -388,7 +402,8 @@ public class DiffRowGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Give the originial old and new text lines to Diffrow without any additional processing.
|
* Give the originial old and new text lines to Diffrow without any additional processing and without any tags to
|
||||||
|
* highlight the change.
|
||||||
*
|
*
|
||||||
* @param val the value to set. Default: false.
|
* @param val the value to set. Default: false.
|
||||||
* @return builder with configured reportLinesUnWrapped parameter
|
* @return builder with configured reportLinesUnWrapped parameter
|
||||||
@@ -401,7 +416,7 @@ public class DiffRowGenerator {
|
|||||||
/**
|
/**
|
||||||
* Generator for Old-Text-Tags.
|
* Generator for Old-Text-Tags.
|
||||||
*
|
*
|
||||||
* @param tag the tag to set. Without angle brackets. Default: span.
|
* @param generator the tag generator
|
||||||
* @return builder with configured ignoreBlankLines parameter
|
* @return builder with configured ignoreBlankLines parameter
|
||||||
*/
|
*/
|
||||||
public Builder oldTag(Function<Boolean, String> generator) {
|
public Builder oldTag(Function<Boolean, String> generator) {
|
||||||
@@ -421,7 +436,7 @@ public class DiffRowGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the column with of generated lines of original and revised texts.
|
* Set the column width of generated lines of original and revised texts.
|
||||||
*
|
*
|
||||||
* @param width the width to set. Making it < 0 doesn't have any sense. Default 80. @return builder with config
|
* @param width the width to set. Making it < 0 doesn't have any sense. Default 80. @return builder with config
|
||||||
* ured ignoreBlankLines parameter
|
* ured ignoreBlankLines parameter
|
||||||
@@ -454,17 +469,41 @@ public class DiffRowGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Per default each character is separatly processed. This variant introduces processing by word, which should
|
* Per default each character is separatly processed. This variant introduces processing by word, which does not
|
||||||
* deliver no in word changes.
|
* deliver in word changes. Therefore the whole word will be tagged as changed:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* false: (aBa : aba) -- changed: a(B)a : a(b)a
|
||||||
|
* true: (aBa : aba) -- changed: (aBa) : (aba)
|
||||||
|
* </pre>
|
||||||
*/
|
*/
|
||||||
public Builder inlineDiffByWord(boolean inlineDiffByWord) {
|
public Builder inlineDiffByWord(boolean inlineDiffByWord) {
|
||||||
inlineDiffSplitter = inlineDiffByWord ? SPLITTER_BY_WORD : SPLITTER_BY_CHARACTER;
|
inlineDiffSplitter = inlineDiffByWord ? SPLITTER_BY_WORD : SPLITTER_BY_CHARACTER;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To provide some customized splitting a splitter can be provided. Here someone could think about sentence splitter,
|
||||||
|
* comma splitter or stuff like that.
|
||||||
|
*
|
||||||
|
* @param inlineDiffSplitter
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public Builder inlineDiffBySplitter(Function<String, List<String>> inlineDiffSplitter) {
|
public Builder inlineDiffBySplitter(Function<String, List<String>> inlineDiffSplitter) {
|
||||||
this.inlineDiffSplitter = inlineDiffSplitter;
|
this.inlineDiffSplitter = inlineDiffSplitter;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* By default DiffRowGenerator preprocesses lines for HTML output. Tabs and special HTML characters like "<"
|
||||||
|
* are replaced with its encoded value. To change this you can provide a customized line normalizer here.
|
||||||
|
*
|
||||||
|
* @param lineNormalizer
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Builder lineNormalizer(Function<String, String> lineNormalizer) {
|
||||||
|
this.lineNormalizer = lineNormalizer;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -34,12 +34,6 @@ final class StringUtils {
|
|||||||
return htmlEntites(str).replace("\t", " ");
|
return htmlEntites(str).replace("\t", " ");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<String> normalize(List<String> list) {
|
|
||||||
return list.stream()
|
|
||||||
.map(StringUtils::normalize)
|
|
||||||
.collect(toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<String> wrapText(List<String> list, int columnWidth) {
|
public static List<String> wrapText(List<String> list, int columnWidth) {
|
||||||
return list.stream()
|
return list.stream()
|
||||||
.map(line -> wrapText(line, columnWidth))
|
.map(line -> wrapText(line, columnWidth))
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 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.unifieddiff;
|
||||||
|
|
||||||
|
import com.github.difflib.patch.PatchFailedException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Tobias Warneke (t.warneke@gmx.net)
|
||||||
|
*/
|
||||||
|
public final class UnifiedDiff {
|
||||||
|
|
||||||
|
private String header;
|
||||||
|
private String tail;
|
||||||
|
private final List<UnifiedDiffFile> files = new ArrayList<>();
|
||||||
|
|
||||||
|
public String getHeader() {
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHeader(String header) {
|
||||||
|
this.header = header;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addFile(UnifiedDiffFile file) {
|
||||||
|
files.add(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<UnifiedDiffFile> getFiles() {
|
||||||
|
return Collections.unmodifiableList(files);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setTailTxt(String tailTxt) {
|
||||||
|
this.tail = tailTxt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTail() {
|
||||||
|
return tail;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> spplyPatchTo(Predicate<String> findFile, List<String> originalLines) throws PatchFailedException {
|
||||||
|
UnifiedDiffFile file = files.stream()
|
||||||
|
.filter(diff -> findFile.test(diff.getFromFile()))
|
||||||
|
.findFirst().orElse(null);
|
||||||
|
if (file != null) {
|
||||||
|
return file.getPatch().applyTo(originalLines);
|
||||||
|
} else {
|
||||||
|
return originalLines;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UnifiedDiff from(String header, String tail, UnifiedDiffFile... files) {
|
||||||
|
UnifiedDiff diff = new UnifiedDiff();
|
||||||
|
diff.setHeader(header);
|
||||||
|
diff.setTailTxt(tail);
|
||||||
|
for (UnifiedDiffFile file : files) {
|
||||||
|
diff.addFile(file);
|
||||||
|
}
|
||||||
|
return diff;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 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.unifieddiff;
|
||||||
|
|
||||||
|
import com.github.difflib.patch.Patch;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Tobias Warneke (t.warneke@gmx.net)
|
||||||
|
*/
|
||||||
|
public final class UnifiedDiffFile {
|
||||||
|
|
||||||
|
private String diffCommand;
|
||||||
|
private String fromFile;
|
||||||
|
private String fromTimestamp;
|
||||||
|
private String toFile;
|
||||||
|
private String toTimestamp;
|
||||||
|
private String index;
|
||||||
|
private Patch<String> patch = new Patch<>();
|
||||||
|
|
||||||
|
public String getDiffCommand() {
|
||||||
|
return diffCommand;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDiffCommand(String diffCommand) {
|
||||||
|
this.diffCommand = diffCommand;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFromFile() {
|
||||||
|
return fromFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFromFile(String fromFile) {
|
||||||
|
this.fromFile = fromFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getToFile() {
|
||||||
|
return toFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setToFile(String toFile) {
|
||||||
|
this.toFile = toFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIndex(String index) {
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIndex() {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Patch<String> getPatch() {
|
||||||
|
return patch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFromTimestamp() {
|
||||||
|
return fromTimestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFromTimestamp(String fromTimestamp) {
|
||||||
|
this.fromTimestamp = fromTimestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getToTimestamp() {
|
||||||
|
return toTimestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setToTimestamp(String toTimestamp) {
|
||||||
|
this.toTimestamp = toTimestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static UnifiedDiffFile from(String fromFile, String toFile, Patch<String> patch) {
|
||||||
|
UnifiedDiffFile file = new UnifiedDiffFile();
|
||||||
|
file.setFromFile(fromFile);
|
||||||
|
file.setToFile(toFile);
|
||||||
|
file.patch = patch;
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 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.unifieddiff;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Tobias Warneke (t.warneke@gmx.net)
|
||||||
|
*/
|
||||||
|
public class UnifiedDiffParserException extends RuntimeException {
|
||||||
|
|
||||||
|
public UnifiedDiffParserException() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnifiedDiffParserException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnifiedDiffParserException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnifiedDiffParserException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnifiedDiffParserException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||||
|
super(message, cause, enableSuppression, writableStackTrace);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,323 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 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.unifieddiff;
|
||||||
|
|
||||||
|
import com.github.difflib.patch.ChangeDelta;
|
||||||
|
import com.github.difflib.patch.Chunk;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
import java.util.regex.MatchResult;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Tobias Warneke (t.warneke@gmx.net)
|
||||||
|
*/
|
||||||
|
public final class UnifiedDiffReader {
|
||||||
|
|
||||||
|
static final Pattern UNIFIED_DIFF_CHUNK_REGEXP = Pattern.compile("^@@\\s+-(?:(\\d+)(?:,(\\d+))?)\\s+\\+(?:(\\d+)(?:,(\\d+))?)\\s+@@");
|
||||||
|
static final Pattern TIMESTAMP_REGEXP = Pattern.compile("(\\d{4}-\\d{2}-\\d{2}[T ]\\d{2}:\\d{2}:\\d{2}\\.\\d{3,})");
|
||||||
|
|
||||||
|
private final InternalUnifiedDiffReader READER;
|
||||||
|
private final UnifiedDiff data = new UnifiedDiff();
|
||||||
|
|
||||||
|
private final UnifiedDiffLine DIFF_COMMAND = new UnifiedDiffLine(true, "^diff\\s", this::processDiff);
|
||||||
|
private final UnifiedDiffLine INDEX = new UnifiedDiffLine(true, "^index\\s[\\da-zA-Z]+\\.\\.[\\da-zA-Z]+(\\s(\\d+))?$", this::processIndex);
|
||||||
|
private final UnifiedDiffLine FROM_FILE = new UnifiedDiffLine(true, "^---\\s", this::processFromFile);
|
||||||
|
private final UnifiedDiffLine TO_FILE = new UnifiedDiffLine(true, "^\\+\\+\\+\\s", this::processToFile);
|
||||||
|
|
||||||
|
private final UnifiedDiffLine CHUNK = new UnifiedDiffLine(false, UNIFIED_DIFF_CHUNK_REGEXP, this::processChunk);
|
||||||
|
private final UnifiedDiffLine LINE_NORMAL = new UnifiedDiffLine("^\\s", this::processNormalLine);
|
||||||
|
private final UnifiedDiffLine LINE_DEL = new UnifiedDiffLine("^-", this::processDelLine);
|
||||||
|
private final UnifiedDiffLine LINE_ADD = new UnifiedDiffLine("^\\+", this::processAddLine);
|
||||||
|
|
||||||
|
private UnifiedDiffFile actualFile;
|
||||||
|
|
||||||
|
UnifiedDiffReader(Reader reader) {
|
||||||
|
this.READER = new InternalUnifiedDiffReader(reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
// schema = [[/^\s+/, normal], [/^diff\s/, start], [/^new file mode \d+$/, new_file],
|
||||||
|
// [/^deleted file mode \d+$/, deleted_file], [/^index\s[\da-zA-Z]+\.\.[\da-zA-Z]+(\s(\d+))?$/, index],
|
||||||
|
// [/^---\s/, from_file], [/^\+\+\+\s/, to_file], [/^@@\s+\-(\d+),?(\d+)?\s+\+(\d+),?(\d+)?\s@@/, chunk],
|
||||||
|
// [/^-/, del], [/^\+/, add], [/^\\ No newline at end of file$/, eof]];
|
||||||
|
private UnifiedDiff parse() throws IOException, UnifiedDiffParserException {
|
||||||
|
String headerTxt = "";
|
||||||
|
LOG.log(Level.INFO, "header parsing");
|
||||||
|
String line = null;
|
||||||
|
while (READER.ready()) {
|
||||||
|
line = READER.readLine();
|
||||||
|
LOG.log(Level.INFO, "parsing line {0}", line);
|
||||||
|
if (DIFF_COMMAND.validLine(line) || INDEX.validLine(line)
|
||||||
|
|| FROM_FILE.validLine(line) || TO_FILE.validLine(line)) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
headerTxt += line + "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!"".equals(headerTxt)) {
|
||||||
|
data.setHeader(headerTxt);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (line != null) {
|
||||||
|
if (!CHUNK.validLine(line)) {
|
||||||
|
initFileIfNecessary();
|
||||||
|
while (!CHUNK.validLine(line)) {
|
||||||
|
if (processLine(line, DIFF_COMMAND, INDEX, FROM_FILE, TO_FILE) == false) {
|
||||||
|
throw new UnifiedDiffParserException("expected file start line not found");
|
||||||
|
}
|
||||||
|
line = READER.readLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
processLine(line, CHUNK);
|
||||||
|
while ((line = READER.readLine()) != null) {
|
||||||
|
if (processLine(line, LINE_NORMAL, LINE_ADD, LINE_DEL) == false) {
|
||||||
|
throw new UnifiedDiffParserException("expected data line not found");
|
||||||
|
}
|
||||||
|
if (originalTxt.size() == old_size && revisedTxt.size() == new_size) {
|
||||||
|
finalizeChunk();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
line = READER.readLine();
|
||||||
|
if (line == null || line.startsWith("--")) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (READER.ready()) {
|
||||||
|
String tailTxt = "";
|
||||||
|
while (READER.ready()) {
|
||||||
|
tailTxt += READER.readLine() + "\n";
|
||||||
|
}
|
||||||
|
data.setTailTxt(tailTxt);
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String[] parseFileNames(String line) {
|
||||||
|
String[] split = line.split(" ");
|
||||||
|
return new String[]{
|
||||||
|
split[2].replaceAll("^a/", ""),
|
||||||
|
split[3].replaceAll("^b/", "")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Logger LOG = Logger.getLogger(UnifiedDiffReader.class.getName());
|
||||||
|
|
||||||
|
public static UnifiedDiff parseUnifiedDiff(InputStream stream) throws IOException, UnifiedDiffParserException {
|
||||||
|
UnifiedDiffReader parser = new UnifiedDiffReader(new BufferedReader(new InputStreamReader(stream)));
|
||||||
|
return parser.parse();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean processLine(String line, UnifiedDiffLine... rules) throws UnifiedDiffParserException {
|
||||||
|
for (UnifiedDiffLine rule : rules) {
|
||||||
|
if (rule.processLine(line)) {
|
||||||
|
LOG.info(" >>> processed rule " + rule.toString());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG.info(" >>> no rule matched " + line);
|
||||||
|
return false;
|
||||||
|
//throw new UnifiedDiffParserException("parsing error at line " + line);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initFileIfNecessary() {
|
||||||
|
if (!originalTxt.isEmpty() || !revisedTxt.isEmpty()) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
actualFile = null;
|
||||||
|
if (actualFile == null) {
|
||||||
|
actualFile = new UnifiedDiffFile();
|
||||||
|
data.addFile(actualFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processDiff(MatchResult match, String line) {
|
||||||
|
//initFileIfNecessary();
|
||||||
|
LOG.log(Level.INFO, "start {0}", line);
|
||||||
|
String[] fromTo = parseFileNames(READER.lastLine());
|
||||||
|
actualFile.setFromFile(fromTo[0]);
|
||||||
|
actualFile.setToFile(fromTo[1]);
|
||||||
|
actualFile.setDiffCommand(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> originalTxt = new ArrayList<>();
|
||||||
|
private List<String> revisedTxt = new ArrayList<>();
|
||||||
|
private int old_ln;
|
||||||
|
private int old_size;
|
||||||
|
private int new_ln;
|
||||||
|
private int new_size;
|
||||||
|
|
||||||
|
private void finalizeChunk() {
|
||||||
|
if (!originalTxt.isEmpty() || !revisedTxt.isEmpty()) {
|
||||||
|
actualFile.getPatch().addDelta(new ChangeDelta<>(new Chunk<>(
|
||||||
|
old_ln - 1, originalTxt), new Chunk<>(
|
||||||
|
new_ln - 1, revisedTxt)));
|
||||||
|
old_ln = 0;
|
||||||
|
new_ln = 0;
|
||||||
|
originalTxt.clear();
|
||||||
|
revisedTxt.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processNormalLine(MatchResult match, String line) {
|
||||||
|
String cline = line.substring(1);
|
||||||
|
originalTxt.add(cline);
|
||||||
|
revisedTxt.add(cline);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processAddLine(MatchResult match, String line) {
|
||||||
|
String cline = line.substring(1);
|
||||||
|
revisedTxt.add(cline);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processDelLine(MatchResult match, String line) {
|
||||||
|
String cline = line.substring(1);
|
||||||
|
originalTxt.add(cline);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processChunk(MatchResult match, String chunkStart) {
|
||||||
|
// finalizeChunk();
|
||||||
|
old_ln = toInteger(match, 1, 1);
|
||||||
|
old_size = toInteger(match, 2, 0);
|
||||||
|
new_ln = toInteger(match, 3, 1);
|
||||||
|
new_size = toInteger(match, 4, 0);
|
||||||
|
if (old_ln == 0) {
|
||||||
|
old_ln = 1;
|
||||||
|
}
|
||||||
|
if (new_ln == 0) {
|
||||||
|
new_ln = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Integer toInteger(MatchResult match, int group, int defValue) throws NumberFormatException {
|
||||||
|
return Integer.valueOf(Objects.toString(match.group(group), "" + defValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processIndex(MatchResult match, String line) {
|
||||||
|
//initFileIfNecessary();
|
||||||
|
LOG.log(Level.INFO, "index {0}", line);
|
||||||
|
actualFile.setIndex(line.substring(6));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processFromFile(MatchResult match, String line) {
|
||||||
|
//initFileIfNecessary();
|
||||||
|
actualFile.setFromFile(extractFileName(line));
|
||||||
|
actualFile.setFromTimestamp(extractTimestamp(line));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processToFile(MatchResult match, String line) {
|
||||||
|
//initFileIfNecessary();
|
||||||
|
actualFile.setToFile(extractFileName(line));
|
||||||
|
actualFile.setToTimestamp(extractTimestamp(line));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String extractFileName(String _line) {
|
||||||
|
Matcher matcher = TIMESTAMP_REGEXP.matcher(_line);
|
||||||
|
String line = _line;
|
||||||
|
if (matcher.find()) {
|
||||||
|
line = line.substring(1, matcher.start());
|
||||||
|
}
|
||||||
|
return line.substring(4).replaceFirst("^(a|b)\\/", "")
|
||||||
|
.replace(TIMESTAMP_REGEXP.toString(), "").trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String extractTimestamp(String line) {
|
||||||
|
Matcher matcher = TIMESTAMP_REGEXP.matcher(line);
|
||||||
|
if (matcher.find()) {
|
||||||
|
return matcher.group();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final class UnifiedDiffLine {
|
||||||
|
|
||||||
|
private final Pattern pattern;
|
||||||
|
private final BiConsumer<MatchResult, String> command;
|
||||||
|
private final boolean stopsHeaderParsing;
|
||||||
|
|
||||||
|
public UnifiedDiffLine(String pattern, BiConsumer<MatchResult, String> command) {
|
||||||
|
this(false, pattern, command);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnifiedDiffLine(boolean stopsHeaderParsing, String pattern, BiConsumer<MatchResult, String> command) {
|
||||||
|
this.pattern = Pattern.compile(pattern);
|
||||||
|
this.command = command;
|
||||||
|
this.stopsHeaderParsing = stopsHeaderParsing;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnifiedDiffLine(boolean stopsHeaderParsing, Pattern pattern, BiConsumer<MatchResult, String> command) {
|
||||||
|
this.pattern = pattern;
|
||||||
|
this.command = command;
|
||||||
|
this.stopsHeaderParsing = stopsHeaderParsing;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean validLine(String line) {
|
||||||
|
Matcher m = pattern.matcher(line);
|
||||||
|
return m.find();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean processLine(String line) throws UnifiedDiffParserException {
|
||||||
|
Matcher m = pattern.matcher(line);
|
||||||
|
if (m.find()) {
|
||||||
|
command.accept(m.toMatchResult(), line);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isStopsHeaderParsing() {
|
||||||
|
return stopsHeaderParsing;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "UnifiedDiffLine{" + "pattern=" + pattern + ", stopsHeaderParsing=" + stopsHeaderParsing + '}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class InternalUnifiedDiffReader extends BufferedReader {
|
||||||
|
|
||||||
|
private String lastLine;
|
||||||
|
|
||||||
|
public InternalUnifiedDiffReader(Reader reader) {
|
||||||
|
super(reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String readLine() throws IOException {
|
||||||
|
lastLine = super.readLine();
|
||||||
|
return lastLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
String lastLine() {
|
||||||
|
return lastLine;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,201 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 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.unifieddiff;
|
||||||
|
|
||||||
|
import com.github.difflib.patch.AbstractDelta;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @todo use an instance to store contextSize and originalLinesProvider.
|
||||||
|
* @author Tobias Warneke (t.warneke@gmx.net)
|
||||||
|
*/
|
||||||
|
public class UnifiedDiffWriter {
|
||||||
|
|
||||||
|
private static final Logger LOG = Logger.getLogger(UnifiedDiffWriter.class.getName());
|
||||||
|
|
||||||
|
public static void write(UnifiedDiff diff, Function<String, List<String>> originalLinesProvider, Writer writer, int contextSize) throws IOException {
|
||||||
|
write(diff, originalLinesProvider, line -> {
|
||||||
|
try {
|
||||||
|
writer.append(line).append("\n");
|
||||||
|
} catch (IOException ex) {
|
||||||
|
LOG.log(Level.SEVERE, null, ex);
|
||||||
|
}
|
||||||
|
}, contextSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void write(UnifiedDiff diff, Function<String, List<String>> originalLinesProvider, Consumer<String> writer, int contextSize) throws IOException {
|
||||||
|
writer.accept(diff.getHeader());
|
||||||
|
|
||||||
|
for (UnifiedDiffFile file : diff.getFiles()) {
|
||||||
|
List<AbstractDelta<String>> patchDeltas = new ArrayList<>(
|
||||||
|
file.getPatch().getDeltas());
|
||||||
|
if (!patchDeltas.isEmpty()) {
|
||||||
|
writeOrNothing(writer, file.getDiffCommand());
|
||||||
|
if (file.getIndex() != null) {
|
||||||
|
writer.accept("index " + file.getIndex());
|
||||||
|
}
|
||||||
|
if (file.getFromFile() != null) {
|
||||||
|
writer.accept("--- " + file.getFromFile());
|
||||||
|
}
|
||||||
|
if (file.getToFile() != null) {
|
||||||
|
writer.accept("+++ " + file.getToFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> originalLines = originalLinesProvider.apply(file.getFromFile());
|
||||||
|
|
||||||
|
List<AbstractDelta<String>> deltas = new ArrayList<>();
|
||||||
|
|
||||||
|
AbstractDelta<String> delta = patchDeltas.get(0);
|
||||||
|
deltas.add(delta); // add the first Delta to the current set
|
||||||
|
// if there's more than 1 Delta, we may need to output them together
|
||||||
|
if (patchDeltas.size() > 1) {
|
||||||
|
for (int i = 1; i < patchDeltas.size(); i++) {
|
||||||
|
int position = delta.getSource().getPosition();
|
||||||
|
|
||||||
|
// Check if the next Delta is too close to the current
|
||||||
|
// position.
|
||||||
|
// And if it is, add it to the current set
|
||||||
|
AbstractDelta<String> nextDelta = patchDeltas.get(i);
|
||||||
|
if ((position + delta.getSource().size() + contextSize) >= (nextDelta
|
||||||
|
.getSource().getPosition() - contextSize)) {
|
||||||
|
deltas.add(nextDelta);
|
||||||
|
} else {
|
||||||
|
// if it isn't, output the current set,
|
||||||
|
// then create a new set and add the current Delta to
|
||||||
|
// it.
|
||||||
|
processDeltas(writer, originalLines, deltas, contextSize);
|
||||||
|
deltas.clear();
|
||||||
|
deltas.add(nextDelta);
|
||||||
|
}
|
||||||
|
delta = nextDelta;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
// don't forget to process the last set of Deltas
|
||||||
|
processDeltas(writer, originalLines, deltas, contextSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (diff.getTail() != null) {
|
||||||
|
writer.accept("--");
|
||||||
|
writer.accept(diff.getTail());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void processDeltas(Consumer<String> writer,
|
||||||
|
List<String> origLines, List<AbstractDelta<String>> deltas,
|
||||||
|
int contextSize) {
|
||||||
|
List<String> buffer = new ArrayList<>();
|
||||||
|
int origTotal = 0; // counter for total lines output from Original
|
||||||
|
int revTotal = 0; // counter for total lines output from Original
|
||||||
|
int line;
|
||||||
|
|
||||||
|
AbstractDelta<String> curDelta = deltas.get(0);
|
||||||
|
|
||||||
|
// NOTE: +1 to overcome the 0-offset Position
|
||||||
|
int origStart = curDelta.getSource().getPosition() + 1 - contextSize;
|
||||||
|
if (origStart < 1) {
|
||||||
|
origStart = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int revStart = curDelta.getTarget().getPosition() + 1 - contextSize;
|
||||||
|
if (revStart < 1) {
|
||||||
|
revStart = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// find the start of the wrapper context code
|
||||||
|
int contextStart = curDelta.getSource().getPosition() - contextSize;
|
||||||
|
if (contextStart < 0) {
|
||||||
|
contextStart = 0; // clamp to the start of the file
|
||||||
|
}
|
||||||
|
|
||||||
|
// output the context before the first Delta
|
||||||
|
for (line = contextStart; line < curDelta.getSource().getPosition(); line++) { //
|
||||||
|
buffer.add(" " + origLines.get(line));
|
||||||
|
origTotal++;
|
||||||
|
revTotal++;
|
||||||
|
}
|
||||||
|
// output the first Delta
|
||||||
|
getDeltaText(txt -> buffer.add(txt), curDelta);
|
||||||
|
origTotal += curDelta.getSource().getLines().size();
|
||||||
|
revTotal += curDelta.getTarget().getLines().size();
|
||||||
|
|
||||||
|
int deltaIndex = 1;
|
||||||
|
while (deltaIndex < deltas.size()) { // for each of the other Deltas
|
||||||
|
AbstractDelta<String> nextDelta = deltas.get(deltaIndex);
|
||||||
|
int intermediateStart = curDelta.getSource().getPosition()
|
||||||
|
+ curDelta.getSource().getLines().size();
|
||||||
|
for (line = intermediateStart; line < nextDelta.getSource()
|
||||||
|
.getPosition(); line++) {
|
||||||
|
// output the code between the last Delta and this one
|
||||||
|
buffer.add(" " + origLines.get(line));
|
||||||
|
origTotal++;
|
||||||
|
revTotal++;
|
||||||
|
}
|
||||||
|
getDeltaText(txt -> buffer.add(txt), nextDelta); // output the Delta
|
||||||
|
origTotal += nextDelta.getSource().getLines().size();
|
||||||
|
revTotal += nextDelta.getTarget().getLines().size();
|
||||||
|
curDelta = nextDelta;
|
||||||
|
deltaIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now output the post-Delta context code, clamping the end of the file
|
||||||
|
contextStart = curDelta.getSource().getPosition()
|
||||||
|
+ curDelta.getSource().getLines().size();
|
||||||
|
for (line = contextStart; (line < (contextStart + contextSize))
|
||||||
|
&& (line < origLines.size()); line++) {
|
||||||
|
buffer.add(" " + origLines.get(line));
|
||||||
|
origTotal++;
|
||||||
|
revTotal++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create and insert the block header, conforming to the Unified Diff
|
||||||
|
// standard
|
||||||
|
writer.accept("@@ -" + origStart + "," + origTotal + " +" + revStart + "," + revTotal + " @@");
|
||||||
|
buffer.forEach(txt -> {
|
||||||
|
writer.accept(txt);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getDeltaText returns the lines to be added to the Unified Diff text from the Delta parameter
|
||||||
|
*
|
||||||
|
* @param delta - the Delta to output
|
||||||
|
* @return list of String lines of code.
|
||||||
|
* @author Bill James (tankerbay@gmail.com)
|
||||||
|
*/
|
||||||
|
private static void getDeltaText(Consumer<String> writer, AbstractDelta<String> delta) {
|
||||||
|
for (String line : delta.getSource().getLines()) {
|
||||||
|
writer.accept("-" + line);
|
||||||
|
}
|
||||||
|
for (String line : delta.getTarget().getLines()) {
|
||||||
|
writer.accept("+" + line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void writeOrNothing(Consumer<String> writer, String str) throws IOException {
|
||||||
|
if (str != null) {
|
||||||
|
writer.accept(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 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.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* This is the first test version of a multifile diff parser. The Api is still subject
|
||||||
|
* of change.
|
||||||
|
*/
|
||||||
|
package com.github.difflib.unifieddiff;
|
||||||
@@ -10,13 +10,14 @@ import java.io.IOException;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static java.util.stream.Collectors.joining;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class GenerateUnifiedDiffTest {
|
public class GenerateUnifiedDiffTest {
|
||||||
|
|
||||||
private static List<String> fileToLines(String filename) throws FileNotFoundException, IOException {
|
public static List<String> fileToLines(String filename) throws FileNotFoundException, IOException {
|
||||||
List<String> lines = new ArrayList<>();
|
List<String> lines = new ArrayList<>();
|
||||||
String line = "";
|
String line = "";
|
||||||
try (BufferedReader in = new BufferedReader(new FileReader(filename))) {
|
try (BufferedReader in = new BufferedReader(new FileReader(filename))) {
|
||||||
@@ -110,11 +111,13 @@ public class GenerateUnifiedDiffTest {
|
|||||||
List<String> unifiedDiff = UnifiedDiffUtils.generateUnifiedDiff(originalFile, revisedFile,
|
List<String> unifiedDiff = UnifiedDiffUtils.generateUnifiedDiff(originalFile, revisedFile,
|
||||||
origLines, patch, 10);
|
origLines, patch, 10);
|
||||||
|
|
||||||
|
System.out.println(unifiedDiff.stream().collect(joining("\n")));
|
||||||
|
|
||||||
Patch<String> fromUnifiedPatch = UnifiedDiffUtils.parseUnifiedDiff(unifiedDiff);
|
Patch<String> fromUnifiedPatch = UnifiedDiffUtils.parseUnifiedDiff(unifiedDiff);
|
||||||
List<String> patchedLines;
|
List<String> patchedLines;
|
||||||
try {
|
try {
|
||||||
patchedLines = (List<String>) fromUnifiedPatch.applyTo(origLines);
|
patchedLines = fromUnifiedPatch.applyTo(origLines);
|
||||||
assertTrue(revLines.size() == patchedLines.size());
|
assertEquals(revLines.size(), patchedLines.size());
|
||||||
for (int i = 0; i < revLines.size(); i++) {
|
for (int i = 0; i < revLines.size(); i++) {
|
||||||
String l1 = revLines.get(i);
|
String l1 = revLines.get(i);
|
||||||
String l2 = patchedLines.get(i);
|
String l2 = patchedLines.get(i);
|
||||||
@@ -10,7 +10,7 @@ public final class TestConstants {
|
|||||||
|
|
||||||
public static final String BASE_FOLDER_RESOURCES = "target/test-classes/";
|
public static final String BASE_FOLDER_RESOURCES = "target/test-classes/";
|
||||||
/**
|
/**
|
||||||
* The base folder containing the test files. Ends with {@link #FS}.
|
* The base folder containing the test files.
|
||||||
*/
|
*/
|
||||||
public static final String MOCK_FOLDER = BASE_FOLDER_RESOURCES + "/mocks/";
|
public static final String MOCK_FOLDER = BASE_FOLDER_RESOURCES + "/mocks/";
|
||||||
|
|
||||||
@@ -5,6 +5,7 @@ import java.io.File;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import static java.util.stream.Collectors.toList;
|
import static java.util.stream.Collectors.toList;
|
||||||
@@ -28,6 +29,16 @@ public class DiffRowGeneratorTest {
|
|||||||
assertEquals(3, rows.size());
|
assertEquals(3, rows.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test of normalize method, of class StringUtils.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testNormalize_List() {
|
||||||
|
DiffRowGenerator generator = DiffRowGenerator.create()
|
||||||
|
.build();
|
||||||
|
assertEquals(Collections.singletonList(" test"), generator.normalizeLines(Collections.singletonList("\ttest")));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGenerator_Default2() throws DiffException {
|
public void testGenerator_Default2() throws DiffException {
|
||||||
String first = "anything \n \nother";
|
String first = "anything \n \nother";
|
||||||
@@ -375,4 +386,35 @@ public class DiffRowGeneratorTest {
|
|||||||
assertEquals("[[CHANGE,This is a test ~senctence~.,This is a test **for diffutils**.], [CHANGE,,**This is the second line.**], [CHANGE,,**And one more.**]]",
|
assertEquals("[[CHANGE,This is a test ~senctence~.,This is a test **for diffutils**.], [CHANGE,,**This is the second line.**], [CHANGE,,**And one more.**]]",
|
||||||
rows.toString());
|
rows.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGeneratorIssue41DefaultNormalizer() throws DiffException {
|
||||||
|
DiffRowGenerator generator = DiffRowGenerator.create()
|
||||||
|
.build();
|
||||||
|
List<DiffRow> rows = generator.generateDiffRows(Arrays.asList("<"), Arrays.asList("<"));
|
||||||
|
assertEquals("[[EQUAL,<,<]]", rows.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGeneratorIssue41UserNormalizer() throws DiffException {
|
||||||
|
DiffRowGenerator generator = DiffRowGenerator.create()
|
||||||
|
.lineNormalizer(str -> str.replace("\t", " "))
|
||||||
|
.build();
|
||||||
|
List<DiffRow> rows = generator.generateDiffRows(Arrays.asList("<"), Arrays.asList("<"));
|
||||||
|
assertEquals("[[EQUAL,<,<]]", rows.toString());
|
||||||
|
rows = generator.generateDiffRows(Arrays.asList("\t<"), Arrays.asList("<"));
|
||||||
|
assertEquals("[[CHANGE, <,<]]", rows.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGenerationIssue44reportLinesUnchangedProblem() throws DiffException {
|
||||||
|
DiffRowGenerator generator = DiffRowGenerator.create()
|
||||||
|
.showInlineDiffs(true)
|
||||||
|
.reportLinesUnchanged(true)
|
||||||
|
.oldTag(f -> "~~")
|
||||||
|
.newTag(f -> "**")
|
||||||
|
.build();
|
||||||
|
List<DiffRow> rows = generator.generateDiffRows(Arrays.asList("<dt>To do</dt>"), Arrays.asList("<dt>Done</dt>"));
|
||||||
|
assertEquals("[[CHANGE,<dt>~~T~~o~~ do~~</dt>,<dt>**D**o**ne**</dt>]]", rows.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -15,7 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.github.difflib.text;
|
package com.github.difflib.text;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@@ -41,14 +40,6 @@ public class StringUtilsTest {
|
|||||||
assertEquals(" test", StringUtils.normalize("\ttest"));
|
assertEquals(" test", StringUtils.normalize("\ttest"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Test of normalize method, of class StringUtils.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testNormalize_List() {
|
|
||||||
assertEquals(Collections.singletonList(" test"), StringUtils.normalize(Collections.singletonList("\ttest")));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test of wrapText method, of class StringUtils.
|
* Test of wrapText method, of class StringUtils.
|
||||||
*/
|
*/
|
||||||
@@ -0,0 +1,144 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 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.unifieddiff;
|
||||||
|
|
||||||
|
import com.github.difflib.patch.AbstractDelta;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import static org.assertj.core.api.Java6Assertions.assertThat;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Tobias Warneke (t.warneke@gmx.net)
|
||||||
|
*/
|
||||||
|
public class UnifiedDiffReaderTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSimpleParse() throws IOException {
|
||||||
|
UnifiedDiff diff = UnifiedDiffReader.parseUnifiedDiff(UnifiedDiffReaderTest.class.getResourceAsStream("jsqlparser_patch_1.diff"));
|
||||||
|
|
||||||
|
System.out.println(diff);
|
||||||
|
|
||||||
|
assertThat(diff.getFiles().size()).isEqualTo(2);
|
||||||
|
|
||||||
|
UnifiedDiffFile file1 = diff.getFiles().get(0);
|
||||||
|
assertThat(file1.getFromFile()).isEqualTo("src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt");
|
||||||
|
assertThat(file1.getPatch().getDeltas().size()).isEqualTo(3);
|
||||||
|
|
||||||
|
assertThat(diff.getTail()).isEqualTo("2.17.1.windows.2\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParseDiffBlock() {
|
||||||
|
String[] files = UnifiedDiffReader.parseFileNames("diff --git a/src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java b/src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java");
|
||||||
|
assertThat(files).containsExactly("src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java", "src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testChunkHeaderParsing() {
|
||||||
|
Pattern pattern = UnifiedDiffReader.UNIFIED_DIFF_CHUNK_REGEXP;
|
||||||
|
Matcher matcher = pattern.matcher("@@ -189,6 +189,7 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */");
|
||||||
|
|
||||||
|
assertTrue(matcher.find());
|
||||||
|
assertEquals("189", matcher.group(1));
|
||||||
|
assertEquals("189", matcher.group(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testChunkHeaderParsing2() {
|
||||||
|
//"^@@\\s+-(?:(\\d+)(?:,(\\d+))?)\\s+\\+(?:(\\d+)(?:,(\\d+))?)\\s+@@.*$"
|
||||||
|
Pattern pattern = UnifiedDiffReader.UNIFIED_DIFF_CHUNK_REGEXP;
|
||||||
|
Matcher matcher = pattern.matcher("@@ -189,6 +189,7 @@");
|
||||||
|
|
||||||
|
assertTrue(matcher.find());
|
||||||
|
assertEquals("189", matcher.group(1));
|
||||||
|
assertEquals("189", matcher.group(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testChunkHeaderParsing3() {
|
||||||
|
//"^@@\\s+-(?:(\\d+)(?:,(\\d+))?)\\s+\\+(?:(\\d+)(?:,(\\d+))?)\\s+@@.*$"
|
||||||
|
Pattern pattern = UnifiedDiffReader.UNIFIED_DIFF_CHUNK_REGEXP;
|
||||||
|
Matcher matcher = pattern.matcher("@@ -1,27 +1,27 @@");
|
||||||
|
|
||||||
|
assertTrue(matcher.find());
|
||||||
|
assertEquals("1", matcher.group(1));
|
||||||
|
assertEquals("1", matcher.group(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSimpleParse2() throws IOException {
|
||||||
|
UnifiedDiff diff = UnifiedDiffReader.parseUnifiedDiff(UnifiedDiffReaderTest.class.getResourceAsStream("jsqlparser_patch_1.diff"));
|
||||||
|
|
||||||
|
System.out.println(diff);
|
||||||
|
|
||||||
|
assertThat(diff.getFiles().size()).isEqualTo(2);
|
||||||
|
|
||||||
|
UnifiedDiffFile file1 = diff.getFiles().get(0);
|
||||||
|
assertThat(file1.getFromFile()).isEqualTo("src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt");
|
||||||
|
assertThat(file1.getPatch().getDeltas().size()).isEqualTo(3);
|
||||||
|
|
||||||
|
AbstractDelta<String> first = file1.getPatch().getDeltas().get(0);
|
||||||
|
|
||||||
|
assertThat(first.getSource().size()).isGreaterThan(0);
|
||||||
|
assertThat(first.getTarget().size()).isGreaterThan(0);
|
||||||
|
|
||||||
|
assertThat(diff.getTail()).isEqualTo("2.17.1.windows.2\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSimplePattern() {
|
||||||
|
Pattern pattern = Pattern.compile("^\\+\\+\\+\\s");
|
||||||
|
|
||||||
|
Matcher m = pattern.matcher("+++ revised.txt");
|
||||||
|
assertTrue(m.find());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParseIssue46() throws IOException {
|
||||||
|
UnifiedDiff diff = UnifiedDiffReader.parseUnifiedDiff(
|
||||||
|
UnifiedDiffReaderTest.class.getResourceAsStream("problem_diff_issue46.diff"));
|
||||||
|
|
||||||
|
System.out.println(diff);
|
||||||
|
|
||||||
|
assertThat(diff.getFiles().size()).isEqualTo(1);
|
||||||
|
|
||||||
|
UnifiedDiffFile file1 = diff.getFiles().get(0);
|
||||||
|
assertThat(file1.getFromFile()).isEqualTo(".vhd");
|
||||||
|
assertThat(file1.getPatch().getDeltas().size()).isEqualTo(1);
|
||||||
|
|
||||||
|
assertThat(diff.getTail()).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParseIssue33() throws IOException {
|
||||||
|
UnifiedDiff diff = UnifiedDiffReader.parseUnifiedDiff(
|
||||||
|
UnifiedDiffReaderTest.class.getResourceAsStream("problem_diff_issue33.diff"));
|
||||||
|
|
||||||
|
assertThat(diff.getFiles().size()).isEqualTo(1);
|
||||||
|
|
||||||
|
UnifiedDiffFile file1 = diff.getFiles().get(0);
|
||||||
|
assertThat(file1.getFromFile()).isEqualTo("Main.java");
|
||||||
|
assertThat(file1.getPatch().getDeltas().size()).isEqualTo(1);
|
||||||
|
|
||||||
|
assertThat(diff.getTail()).isNull();
|
||||||
|
assertThat(diff.getHeader()).isNull();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,167 @@
|
|||||||
|
package com.github.difflib.unifieddiff;
|
||||||
|
|
||||||
|
import com.github.difflib.DiffUtils;
|
||||||
|
import com.github.difflib.TestConstants;
|
||||||
|
import com.github.difflib.algorithm.DiffException;
|
||||||
|
import com.github.difflib.patch.Patch;
|
||||||
|
import com.github.difflib.patch.PatchFailedException;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import static java.util.stream.Collectors.joining;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class UnifiedDiffRoundTripTest {
|
||||||
|
|
||||||
|
public static List<String> fileToLines(String filename) throws FileNotFoundException, IOException {
|
||||||
|
List<String> lines = new ArrayList<>();
|
||||||
|
String line = "";
|
||||||
|
try (BufferedReader in = new BufferedReader(new FileReader(filename))) {
|
||||||
|
while ((line = in.readLine()) != null) {
|
||||||
|
lines.add(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGenerateUnified() throws DiffException, IOException {
|
||||||
|
List<String> origLines = fileToLines(TestConstants.MOCK_FOLDER + "original.txt");
|
||||||
|
List<String> revLines = fileToLines(TestConstants.MOCK_FOLDER + "revised.txt");
|
||||||
|
|
||||||
|
verify(origLines, revLines, "original.txt", "revised.txt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGenerateUnifiedWithOneDelta() throws DiffException, IOException {
|
||||||
|
List<String> origLines = fileToLines(TestConstants.MOCK_FOLDER + "one_delta_test_original.txt");
|
||||||
|
List<String> revLines = fileToLines(TestConstants.MOCK_FOLDER + "one_delta_test_revised.txt");
|
||||||
|
|
||||||
|
verify(origLines, revLines, "one_delta_test_original.txt", "one_delta_test_revised.txt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGenerateUnifiedDiffWithoutAnyDeltas() throws DiffException, IOException {
|
||||||
|
List<String> test = Arrays.asList("abc");
|
||||||
|
Patch<String> patch = DiffUtils.diff(test, test);
|
||||||
|
StringWriter writer = new StringWriter();
|
||||||
|
|
||||||
|
UnifiedDiffWriter.write(
|
||||||
|
UnifiedDiff.from("header", "tail", UnifiedDiffFile.from("abc", "abc", patch)),
|
||||||
|
name -> test,
|
||||||
|
writer, 0);
|
||||||
|
|
||||||
|
System.out.println(writer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDiff_Issue10() throws IOException {
|
||||||
|
final List<String> baseLines = fileToLines(TestConstants.MOCK_FOLDER + "issue10_base.txt");
|
||||||
|
final List<String> patchLines = fileToLines(TestConstants.MOCK_FOLDER + "issue10_patch.txt");
|
||||||
|
|
||||||
|
UnifiedDiff unifiedDiff = UnifiedDiffReader.parseUnifiedDiff(
|
||||||
|
new ByteArrayInputStream(patchLines.stream().collect(joining("\n")).getBytes())
|
||||||
|
);
|
||||||
|
|
||||||
|
final Patch<String> p = unifiedDiff.getFiles().get(0).getPatch();
|
||||||
|
try {
|
||||||
|
DiffUtils.patch(baseLines, p);
|
||||||
|
} catch (PatchFailedException e) {
|
||||||
|
fail(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Issue 12
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
@Ignore
|
||||||
|
public void testPatchWithNoDeltas() throws DiffException, IOException {
|
||||||
|
final List<String> lines1 = fileToLines(TestConstants.MOCK_FOLDER + "issue11_1.txt");
|
||||||
|
final List<String> lines2 = fileToLines(TestConstants.MOCK_FOLDER + "issue11_2.txt");
|
||||||
|
verify(lines1, lines2, "issue11_1.txt", "issue11_2.txt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDiff5() throws DiffException, IOException {
|
||||||
|
final List<String> lines1 = fileToLines(TestConstants.MOCK_FOLDER + "5A.txt");
|
||||||
|
final List<String> lines2 = fileToLines(TestConstants.MOCK_FOLDER + "5B.txt");
|
||||||
|
verify(lines1, lines2, "5A.txt", "5B.txt");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Issue 19
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testDiffWithHeaderLineInText() throws DiffException, IOException {
|
||||||
|
List<String> original = new ArrayList<>();
|
||||||
|
List<String> revised = new ArrayList<>();
|
||||||
|
|
||||||
|
original.add("test line1");
|
||||||
|
original.add("test line2");
|
||||||
|
original.add("test line 4");
|
||||||
|
original.add("test line 5");
|
||||||
|
|
||||||
|
revised.add("test line1");
|
||||||
|
revised.add("test line2");
|
||||||
|
revised.add("@@ -2,6 +2,7 @@");
|
||||||
|
revised.add("test line 4");
|
||||||
|
revised.add("test line 5");
|
||||||
|
|
||||||
|
Patch<String> patch = DiffUtils.diff(original, revised);
|
||||||
|
StringWriter writer = new StringWriter();
|
||||||
|
UnifiedDiffWriter.write(
|
||||||
|
UnifiedDiff.from("header", "tail", UnifiedDiffFile.from("original", "revised", patch)),
|
||||||
|
name -> original,
|
||||||
|
writer, 10);
|
||||||
|
|
||||||
|
System.out.println(writer.toString());
|
||||||
|
|
||||||
|
UnifiedDiff unifiedDiff = UnifiedDiffReader.parseUnifiedDiff(new ByteArrayInputStream(writer.toString().getBytes()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verify(List<String> origLines, List<String> revLines,
|
||||||
|
String originalFile, String revisedFile) throws DiffException, IOException {
|
||||||
|
Patch<String> patch = DiffUtils.diff(origLines, revLines);
|
||||||
|
|
||||||
|
StringWriter writer = new StringWriter();
|
||||||
|
UnifiedDiffWriter.write(
|
||||||
|
UnifiedDiff.from("header", "tail", UnifiedDiffFile.from(originalFile, revisedFile, patch)),
|
||||||
|
name -> origLines,
|
||||||
|
writer, 10);
|
||||||
|
|
||||||
|
System.out.println(writer.toString());
|
||||||
|
|
||||||
|
UnifiedDiff unifiedDiff = UnifiedDiffReader.parseUnifiedDiff(new ByteArrayInputStream(writer.toString().getBytes()));
|
||||||
|
|
||||||
|
List<String> patchedLines;
|
||||||
|
try {
|
||||||
|
// if (unifiedDiff.getFiles().isEmpty()) {
|
||||||
|
// patchedLines = new ArrayList<>(origLines);
|
||||||
|
// } else {
|
||||||
|
// Patch<String> fromUnifiedPatch = unifiedDiff.getFiles().get(0).getPatch();
|
||||||
|
// patchedLines = fromUnifiedPatch.applyTo(origLines);
|
||||||
|
// }
|
||||||
|
patchedLines = unifiedDiff.spplyPatchTo(file -> originalFile.equals(file), origLines);
|
||||||
|
assertEquals(revLines.size(), patchedLines.size());
|
||||||
|
for (int i = 0; i < revLines.size(); i++) {
|
||||||
|
String l1 = revLines.get(i);
|
||||||
|
String l2 = patchedLines.get(i);
|
||||||
|
if (!l1.equals(l2)) {
|
||||||
|
fail("Line " + (i + 1) + " of the patched file did not match the revised original");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (PatchFailedException e) {
|
||||||
|
fail(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 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.unifieddiff;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Tobias Warneke (t.warneke@gmx.net)
|
||||||
|
*/
|
||||||
|
public class UnifiedDiffWriterTest {
|
||||||
|
|
||||||
|
public UnifiedDiffWriterTest() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWrite() throws URISyntaxException, IOException {
|
||||||
|
String str = readFile(UnifiedDiffReaderTest.class.getResource("jsqlparser_patch_1.diff").toURI(), Charset.defaultCharset());
|
||||||
|
UnifiedDiff diff = UnifiedDiffReader.parseUnifiedDiff(new ByteArrayInputStream(str.getBytes()));
|
||||||
|
|
||||||
|
StringWriter writer = new StringWriter();
|
||||||
|
// UnifiedDiffWriter.write(diff, writer);
|
||||||
|
// System.out.println(writer.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
static String readFile(URI path, Charset encoding)
|
||||||
|
throws IOException {
|
||||||
|
byte[] encoded = Files.readAllBytes(Paths.get(path));
|
||||||
|
return new String(encoded, encoding);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
From 3209a16c55c1976d5b772c607fd4b9d5fb9f9483 Mon Sep 17 00:00:00 2001
|
||||||
|
From: wumpz <t.warneke@gmx.net>
|
||||||
|
Date: Tue, 19 Feb 2019 01:35:14 +0100
|
||||||
|
Subject: [PATCH] fixes #753
|
||||||
|
|
||||||
|
---
|
||||||
|
src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt | 5 +++--
|
||||||
|
.../net/sf/jsqlparser/statement/select/SelectTest.java | 7 +++++++
|
||||||
|
2 files changed, 10 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt
|
||||||
|
index cd9bcd1..5f4b2b7 100644
|
||||||
|
--- a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt
|
||||||
|
+++ b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt
|
||||||
|
@@ -189,6 +189,7 @@ TOKEN: /* SQL Keywords. prefixed with K_ to avoid name clashes */
|
||||||
|
| <K_JOIN:"JOIN">
|
||||||
|
| <K_KEEP:"KEEP">
|
||||||
|
| <K_KEY:"KEY">
|
||||||
|
+| <K_FN:"FN">
|
||||||
|
| <K_LAST: "LAST">
|
||||||
|
| <K_LATERAL:"LATERAL">
|
||||||
|
| <K_LEADING:"LEADING">
|
||||||
|
@@ -1039,7 +1040,7 @@ String RelObjectNameWithoutValue() :
|
||||||
|
| tk=<K_INSERT> | tk=<K_INDEX> | tk=<K_PRIMARY> | tk=<K_ENABLE>
|
||||||
|
| tk=<K_UNSIGNED>
|
||||||
|
| tk=<K_TEMP> | tk=<K_TEMPORARY> | tk=<K_TYPE> | tk=<K_ISNULL>
|
||||||
|
- | tk=<K_ZONE> | tk=<K_COLUMNS> | tk=<K_DESCRIBE>
|
||||||
|
+ | tk=<K_ZONE> | tk=<K_COLUMNS> | tk=<K_DESCRIBE> | tk=<K_FN>
|
||||||
|
/* | tk=<K_PLACING> | tk=<K_BOTH> | tk=<K_LEADING> | tk=<K_TRAILING> */
|
||||||
|
)
|
||||||
|
|
||||||
|
@@ -3118,7 +3119,7 @@ Function Function() #Function:
|
||||||
|
Expression expr1 = null;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
- ["{fn" { retval.setEscaped(true); } ]
|
||||||
|
+ ["{" <K_FN> { retval.setEscaped(true); } ]
|
||||||
|
|
||||||
|
funcName=RelObjectNameExt()
|
||||||
|
|
||||||
|
diff --git a/src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java b/src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java
|
||||||
|
index 7ee9b38..d39bfd3 100644
|
||||||
|
--- a/src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java
|
||||||
|
+++ b/src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java
|
||||||
|
@@ -1063,6 +1063,13 @@ public class SelectTest {
|
||||||
|
assertSqlCanBeParsedAndDeparsed("SELECT {fn concat(a, b)} AS COL");
|
||||||
|
}
|
||||||
|
|
||||||
|
+ @Test
|
||||||
|
+ public void testEscapedFunctionsIssue753() throws JSQLParserException {
|
||||||
|
+ Statement stmt = CCJSqlParserUtil.parse("SELECT { fn test(0)} AS COL");
|
||||||
|
+ assertEquals("SELECT {fn test(0)} AS COL", stmt.toString());
|
||||||
|
+ assertSqlCanBeParsedAndDeparsed("SELECT fn FROM fn");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
@Test
|
||||||
|
public void testNamedParametersPR702() throws JSQLParserException {
|
||||||
|
assertSqlCanBeParsedAndDeparsed("SELECT substring(id, 2, 3), substring(id from 2 for 3), substring(id from 2), trim(BOTH ' ' from 'foo bar '), trim(LEADING ' ' from 'foo bar '), trim(TRAILING ' ' from 'foo bar '), trim(' ' from 'foo bar '), position('foo' in 'bar'), overlay('foo' placing 'bar' from 1), overlay('foo' placing 'bar' from 1 for 2) FROM my table");
|
||||||
|
--
|
||||||
|
2.17.1.windows.2
|
||||||
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
--- a/Main.java
|
||||||
|
+++ b/Main.java
|
||||||
|
@@ -2,2 +2,3 @@ public class Main {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
+ System.out.println("Hello, world!");
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
--- a.vhd 2019-04-18 13:49:39.516149751 +0200
|
||||||
|
+++ b.vhd 2019-04-18 11:33:08.372563078 +0200
|
||||||
|
@@ -2819,3 +2819,2 @@
|
||||||
|
--- some comment
|
||||||
|
-bla
|
||||||
|
-bla
|
||||||
|
+
|
||||||
|
+
|
||||||
@@ -1,372 +1,372 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
#
|
#
|
||||||
# Copyright (c) 2006 Johannes E. Schindelin
|
# Copyright (c) 2006 Johannes E. Schindelin
|
||||||
#
|
#
|
||||||
|
|
||||||
test_description='Test special whitespace in diff engine.
|
test_description='Test special whitespace in diff engine.
|
||||||
|
|
||||||
'
|
'
|
||||||
. ./test-lib.sh
|
. ./test-lib.sh
|
||||||
. ../diff-lib.sh
|
. ../diff-lib.sh
|
||||||
|
|
||||||
# Ray Lehtiniemi's example
|
# Ray Lehtiniemi's example
|
||||||
|
|
||||||
cat << EOF > x
|
cat << EOF > x
|
||||||
do {
|
do {
|
||||||
nothing;
|
nothing;
|
||||||
} while (0);
|
} while (0);
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
git update-index --add x
|
git update-index --add x
|
||||||
|
|
||||||
cat << EOF > x
|
cat << EOF > x
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
nothing;
|
nothing;
|
||||||
}
|
}
|
||||||
while (0);
|
while (0);
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
cat << EOF > expect
|
cat << EOF > expect
|
||||||
diff --git a/x b/x
|
diff --git a/x b/x
|
||||||
index adf3937..6edc172 100644
|
index adf3937..6edc172 100644
|
||||||
--- a/x
|
--- a/x
|
||||||
+++ b/x
|
+++ b/x
|
||||||
@@ -1,3 +1,5 @@
|
@@ -1,3 +1,5 @@
|
||||||
-do {
|
-do {
|
||||||
+do
|
+do
|
||||||
+{
|
+{
|
||||||
nothing;
|
nothing;
|
||||||
-} while (0);
|
-} while (0);
|
||||||
+}
|
+}
|
||||||
+while (0);
|
+while (0);
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
git diff > out
|
git diff > out
|
||||||
test_expect_success "Ray's example without options" 'test_cmp expect out'
|
test_expect_success "Ray's example without options" 'test_cmp expect out'
|
||||||
|
|
||||||
git diff -w > out
|
git diff -w > out
|
||||||
test_expect_success "Ray's example with -w" 'test_cmp expect out'
|
test_expect_success "Ray's example with -w" 'test_cmp expect out'
|
||||||
|
|
||||||
git diff -b > out
|
git diff -b > out
|
||||||
test_expect_success "Ray's example with -b" 'test_cmp expect out'
|
test_expect_success "Ray's example with -b" 'test_cmp expect out'
|
||||||
|
|
||||||
tr 'Q' '\015' << EOF > x
|
tr 'Q' '\015' << EOF > x
|
||||||
whitespace at beginning
|
whitespace at beginning
|
||||||
whitespace change
|
whitespace change
|
||||||
whitespace in the middle
|
whitespace in the middle
|
||||||
whitespace at end
|
whitespace at end
|
||||||
unchanged line
|
unchanged line
|
||||||
CR at endQ
|
CR at endQ
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
git update-index x
|
git update-index x
|
||||||
|
|
||||||
tr '_' ' ' << EOF > x
|
tr '_' ' ' << EOF > x
|
||||||
whitespace at beginning
|
whitespace at beginning
|
||||||
whitespace change
|
whitespace change
|
||||||
white space in the middle
|
white space in the middle
|
||||||
whitespace at end__
|
whitespace at end__
|
||||||
unchanged line
|
unchanged line
|
||||||
CR at end
|
CR at end
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
tr 'Q_' '\015 ' << EOF > expect
|
tr 'Q_' '\015 ' << EOF > expect
|
||||||
diff --git a/x b/x
|
diff --git a/x b/x
|
||||||
index d99af23..8b32fb5 100644
|
index d99af23..8b32fb5 100644
|
||||||
--- a/x
|
--- a/x
|
||||||
+++ b/x
|
+++ b/x
|
||||||
@@ -1,6 +1,6 @@
|
@@ -1,6 +1,6 @@
|
||||||
-whitespace at beginning
|
-whitespace at beginning
|
||||||
-whitespace change
|
-whitespace change
|
||||||
-whitespace in the middle
|
-whitespace in the middle
|
||||||
-whitespace at end
|
-whitespace at end
|
||||||
+ whitespace at beginning
|
+ whitespace at beginning
|
||||||
+whitespace change
|
+whitespace change
|
||||||
+white space in the middle
|
+white space in the middle
|
||||||
+whitespace at end__
|
+whitespace at end__
|
||||||
unchanged line
|
unchanged line
|
||||||
-CR at endQ
|
-CR at endQ
|
||||||
+CR at end
|
+CR at end
|
||||||
EOF
|
EOF
|
||||||
git diff > out
|
git diff > out
|
||||||
test_expect_success 'another test, without options' 'test_cmp expect out'
|
test_expect_success 'another test, without options' 'test_cmp expect out'
|
||||||
|
|
||||||
cat << EOF > expect
|
cat << EOF > expect
|
||||||
diff --git a/x b/x
|
diff --git a/x b/x
|
||||||
index d99af23..8b32fb5 100644
|
index d99af23..8b32fb5 100644
|
||||||
EOF
|
EOF
|
||||||
git diff -w > out
|
git diff -w > out
|
||||||
test_expect_success 'another test, with -w' 'test_cmp expect out'
|
test_expect_success 'another test, with -w' 'test_cmp expect out'
|
||||||
|
|
||||||
tr 'Q' '\015' << EOF > expect
|
tr 'Q' '\015' << EOF > expect
|
||||||
diff --git a/x b/x
|
diff --git a/x b/x
|
||||||
index d99af23..8b32fb5 100644
|
index d99af23..8b32fb5 100644
|
||||||
--- a/x
|
--- a/x
|
||||||
+++ b/x
|
+++ b/x
|
||||||
@@ -1,6 +1,6 @@
|
@@ -1,6 +1,6 @@
|
||||||
-whitespace at beginning
|
-whitespace at beginning
|
||||||
+ whitespace at beginning
|
+ whitespace at beginning
|
||||||
whitespace change
|
whitespace change
|
||||||
-whitespace in the middle
|
-whitespace in the middle
|
||||||
+white space in the middle
|
+white space in the middle
|
||||||
whitespace at end
|
whitespace at end
|
||||||
unchanged line
|
unchanged line
|
||||||
CR at endQ
|
CR at endQ
|
||||||
EOF
|
EOF
|
||||||
git diff -b > out
|
git diff -b > out
|
||||||
test_expect_success 'another test, with -b' 'test_cmp expect out'
|
test_expect_success 'another test, with -b' 'test_cmp expect out'
|
||||||
|
|
||||||
test_expect_success 'check mixed spaces and tabs in indent' '
|
test_expect_success 'check mixed spaces and tabs in indent' '
|
||||||
|
|
||||||
# This is indented with SP HT SP.
|
# This is indented with SP HT SP.
|
||||||
echo " foo();" > x &&
|
echo " foo();" > x &&
|
||||||
git diff --check | grep "space before tab in indent"
|
git diff --check | grep "space before tab in indent"
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check mixed tabs and spaces in indent' '
|
test_expect_success 'check mixed tabs and spaces in indent' '
|
||||||
|
|
||||||
# This is indented with HT SP HT.
|
# This is indented with HT SP HT.
|
||||||
echo " foo();" > x &&
|
echo " foo();" > x &&
|
||||||
git diff --check | grep "space before tab in indent"
|
git diff --check | grep "space before tab in indent"
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check with no whitespace errors' '
|
test_expect_success 'check with no whitespace errors' '
|
||||||
|
|
||||||
git commit -m "snapshot" &&
|
git commit -m "snapshot" &&
|
||||||
echo "foo();" > x &&
|
echo "foo();" > x &&
|
||||||
git diff --check
|
git diff --check
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check with trailing whitespace' '
|
test_expect_success 'check with trailing whitespace' '
|
||||||
|
|
||||||
echo "foo(); " > x &&
|
echo "foo(); " > x &&
|
||||||
test_must_fail git diff --check
|
test_must_fail git diff --check
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check with space before tab in indent' '
|
test_expect_success 'check with space before tab in indent' '
|
||||||
|
|
||||||
# indent has space followed by hard tab
|
# indent has space followed by hard tab
|
||||||
echo " foo();" > x &&
|
echo " foo();" > x &&
|
||||||
test_must_fail git diff --check
|
test_must_fail git diff --check
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success '--check and --exit-code are not exclusive' '
|
test_expect_success '--check and --exit-code are not exclusive' '
|
||||||
|
|
||||||
git checkout x &&
|
git checkout x &&
|
||||||
git diff --check --exit-code
|
git diff --check --exit-code
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success '--check and --quiet are not exclusive' '
|
test_expect_success '--check and --quiet are not exclusive' '
|
||||||
|
|
||||||
git diff --check --quiet
|
git diff --check --quiet
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check staged with no whitespace errors' '
|
test_expect_success 'check staged with no whitespace errors' '
|
||||||
|
|
||||||
echo "foo();" > x &&
|
echo "foo();" > x &&
|
||||||
git add x &&
|
git add x &&
|
||||||
git diff --cached --check
|
git diff --cached --check
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check staged with trailing whitespace' '
|
test_expect_success 'check staged with trailing whitespace' '
|
||||||
|
|
||||||
echo "foo(); " > x &&
|
echo "foo(); " > x &&
|
||||||
git add x &&
|
git add x &&
|
||||||
test_must_fail git diff --cached --check
|
test_must_fail git diff --cached --check
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check staged with space before tab in indent' '
|
test_expect_success 'check staged with space before tab in indent' '
|
||||||
|
|
||||||
# indent has space followed by hard tab
|
# indent has space followed by hard tab
|
||||||
echo " foo();" > x &&
|
echo " foo();" > x &&
|
||||||
git add x &&
|
git add x &&
|
||||||
test_must_fail git diff --cached --check
|
test_must_fail git diff --cached --check
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check with no whitespace errors (diff-index)' '
|
test_expect_success 'check with no whitespace errors (diff-index)' '
|
||||||
|
|
||||||
echo "foo();" > x &&
|
echo "foo();" > x &&
|
||||||
git add x &&
|
git add x &&
|
||||||
git diff-index --check HEAD
|
git diff-index --check HEAD
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check with trailing whitespace (diff-index)' '
|
test_expect_success 'check with trailing whitespace (diff-index)' '
|
||||||
|
|
||||||
echo "foo(); " > x &&
|
echo "foo(); " > x &&
|
||||||
git add x &&
|
git add x &&
|
||||||
test_must_fail git diff-index --check HEAD
|
test_must_fail git diff-index --check HEAD
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check with space before tab in indent (diff-index)' '
|
test_expect_success 'check with space before tab in indent (diff-index)' '
|
||||||
|
|
||||||
# indent has space followed by hard tab
|
# indent has space followed by hard tab
|
||||||
echo " foo();" > x &&
|
echo " foo();" > x &&
|
||||||
git add x &&
|
git add x &&
|
||||||
test_must_fail git diff-index --check HEAD
|
test_must_fail git diff-index --check HEAD
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check staged with no whitespace errors (diff-index)' '
|
test_expect_success 'check staged with no whitespace errors (diff-index)' '
|
||||||
|
|
||||||
echo "foo();" > x &&
|
echo "foo();" > x &&
|
||||||
git add x &&
|
git add x &&
|
||||||
git diff-index --cached --check HEAD
|
git diff-index --cached --check HEAD
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check staged with trailing whitespace (diff-index)' '
|
test_expect_success 'check staged with trailing whitespace (diff-index)' '
|
||||||
|
|
||||||
echo "foo(); " > x &&
|
echo "foo(); " > x &&
|
||||||
git add x &&
|
git add x &&
|
||||||
test_must_fail git diff-index --cached --check HEAD
|
test_must_fail git diff-index --cached --check HEAD
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check staged with space before tab in indent (diff-index)' '
|
test_expect_success 'check staged with space before tab in indent (diff-index)' '
|
||||||
|
|
||||||
# indent has space followed by hard tab
|
# indent has space followed by hard tab
|
||||||
echo " foo();" > x &&
|
echo " foo();" > x &&
|
||||||
git add x &&
|
git add x &&
|
||||||
test_must_fail git diff-index --cached --check HEAD
|
test_must_fail git diff-index --cached --check HEAD
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check with no whitespace errors (diff-tree)' '
|
test_expect_success 'check with no whitespace errors (diff-tree)' '
|
||||||
|
|
||||||
echo "foo();" > x &&
|
echo "foo();" > x &&
|
||||||
git commit -m "new commit" x &&
|
git commit -m "new commit" x &&
|
||||||
git diff-tree --check HEAD^ HEAD
|
git diff-tree --check HEAD^ HEAD
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check with trailing whitespace (diff-tree)' '
|
test_expect_success 'check with trailing whitespace (diff-tree)' '
|
||||||
|
|
||||||
echo "foo(); " > x &&
|
echo "foo(); " > x &&
|
||||||
git commit -m "another commit" x &&
|
git commit -m "another commit" x &&
|
||||||
test_must_fail git diff-tree --check HEAD^ HEAD
|
test_must_fail git diff-tree --check HEAD^ HEAD
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check with space before tab in indent (diff-tree)' '
|
test_expect_success 'check with space before tab in indent (diff-tree)' '
|
||||||
|
|
||||||
# indent has space followed by hard tab
|
# indent has space followed by hard tab
|
||||||
echo " foo();" > x &&
|
echo " foo();" > x &&
|
||||||
git commit -m "yet another" x &&
|
git commit -m "yet another" x &&
|
||||||
test_must_fail git diff-tree --check HEAD^ HEAD
|
test_must_fail git diff-tree --check HEAD^ HEAD
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check trailing whitespace (trailing-space: off)' '
|
test_expect_success 'check trailing whitespace (trailing-space: off)' '
|
||||||
|
|
||||||
git config core.whitespace "-trailing-space" &&
|
git config core.whitespace "-trailing-space" &&
|
||||||
echo "foo (); " > x &&
|
echo "foo (); " > x &&
|
||||||
git diff --check
|
git diff --check
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check trailing whitespace (trailing-space: on)' '
|
test_expect_success 'check trailing whitespace (trailing-space: on)' '
|
||||||
|
|
||||||
git config core.whitespace "trailing-space" &&
|
git config core.whitespace "trailing-space" &&
|
||||||
echo "foo (); " > x &&
|
echo "foo (); " > x &&
|
||||||
test_must_fail git diff --check
|
test_must_fail git diff --check
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check space before tab in indent (space-before-tab: off)' '
|
test_expect_success 'check space before tab in indent (space-before-tab: off)' '
|
||||||
|
|
||||||
# indent contains space followed by HT
|
# indent contains space followed by HT
|
||||||
git config core.whitespace "-space-before-tab" &&
|
git config core.whitespace "-space-before-tab" &&
|
||||||
echo " foo ();" > x &&
|
echo " foo ();" > x &&
|
||||||
git diff --check
|
git diff --check
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check space before tab in indent (space-before-tab: on)' '
|
test_expect_success 'check space before tab in indent (space-before-tab: on)' '
|
||||||
|
|
||||||
# indent contains space followed by HT
|
# indent contains space followed by HT
|
||||||
git config core.whitespace "space-before-tab" &&
|
git config core.whitespace "space-before-tab" &&
|
||||||
echo " foo (); " > x &&
|
echo " foo (); " > x &&
|
||||||
test_must_fail git diff --check
|
test_must_fail git diff --check
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check spaces as indentation (indent-with-non-tab: off)' '
|
test_expect_success 'check spaces as indentation (indent-with-non-tab: off)' '
|
||||||
|
|
||||||
git config core.whitespace "-indent-with-non-tab"
|
git config core.whitespace "-indent-with-non-tab"
|
||||||
echo " foo ();" > x &&
|
echo " foo ();" > x &&
|
||||||
git diff --check
|
git diff --check
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check spaces as indentation (indent-with-non-tab: on)' '
|
test_expect_success 'check spaces as indentation (indent-with-non-tab: on)' '
|
||||||
|
|
||||||
git config core.whitespace "indent-with-non-tab" &&
|
git config core.whitespace "indent-with-non-tab" &&
|
||||||
echo " foo ();" > x &&
|
echo " foo ();" > x &&
|
||||||
test_must_fail git diff --check
|
test_must_fail git diff --check
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check tabs and spaces as indentation (indent-with-non-tab: on)' '
|
test_expect_success 'check tabs and spaces as indentation (indent-with-non-tab: on)' '
|
||||||
|
|
||||||
git config core.whitespace "indent-with-non-tab" &&
|
git config core.whitespace "indent-with-non-tab" &&
|
||||||
echo " foo ();" > x &&
|
echo " foo ();" > x &&
|
||||||
test_must_fail git diff --check
|
test_must_fail git diff --check
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'line numbers in --check output are correct' '
|
test_expect_success 'line numbers in --check output are correct' '
|
||||||
|
|
||||||
echo "" > x &&
|
echo "" > x &&
|
||||||
echo "foo(); " >> x &&
|
echo "foo(); " >> x &&
|
||||||
git diff --check | grep "x:2:"
|
git diff --check | grep "x:2:"
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'checkdiff detects trailing blank lines' '
|
test_expect_success 'checkdiff detects trailing blank lines' '
|
||||||
echo "foo();" >x &&
|
echo "foo();" >x &&
|
||||||
echo "" >>x &&
|
echo "" >>x &&
|
||||||
git diff --check | grep "ends with blank"
|
git diff --check | grep "ends with blank"
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'checkdiff allows new blank lines' '
|
test_expect_success 'checkdiff allows new blank lines' '
|
||||||
git checkout x &&
|
git checkout x &&
|
||||||
mv x y &&
|
mv x y &&
|
||||||
(
|
(
|
||||||
echo "/* This is new */" &&
|
echo "/* This is new */" &&
|
||||||
echo "" &&
|
echo "" &&
|
||||||
cat y
|
cat y
|
||||||
) >x &&
|
) >x &&
|
||||||
git diff --check
|
git diff --check
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'combined diff with autocrlf conversion' '
|
test_expect_success 'combined diff with autocrlf conversion' '
|
||||||
|
|
||||||
git reset --hard &&
|
git reset --hard &&
|
||||||
echo >x hello &&
|
echo >x hello &&
|
||||||
git commit -m "one side" x &&
|
git commit -m "one side" x &&
|
||||||
git checkout HEAD^ &&
|
git checkout HEAD^ &&
|
||||||
echo >x goodbye &&
|
echo >x goodbye &&
|
||||||
git commit -m "the other side" x &&
|
git commit -m "the other side" x &&
|
||||||
git config core.autocrlf true &&
|
git config core.autocrlf true &&
|
||||||
test_must_fail git merge master &&
|
test_must_fail git merge master &&
|
||||||
|
|
||||||
git diff | sed -e "1,/^@@@/d" >actual &&
|
git diff | sed -e "1,/^@@@/d" >actual &&
|
||||||
! grep "^-" actual
|
! grep "^-" actual
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
|
||||||
@@ -1,381 +1,381 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
#
|
#
|
||||||
# Copyright (c) 2006 Johannes E. Schindelin
|
# Copyright (c) 2006 Johannes E. Schindelin
|
||||||
#
|
#
|
||||||
|
|
||||||
test_description='Test special whitespace in diff engine.
|
test_description='Test special whitespace in diff engine.
|
||||||
|
|
||||||
'
|
'
|
||||||
. ./test-lib.sh
|
. ./test-lib.sh
|
||||||
. ../diff-lib.sh
|
. ../diff-lib.sh
|
||||||
|
|
||||||
# Ray Lehtiniemi's example
|
# Ray Lehtiniemi's example
|
||||||
|
|
||||||
cat << EOF > x
|
cat << EOF > x
|
||||||
do {
|
do {
|
||||||
nothing;
|
nothing;
|
||||||
} while (0);
|
} while (0);
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
git update-index --add x
|
git update-index --add x
|
||||||
|
|
||||||
cat << EOF > x
|
cat << EOF > x
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
nothing;
|
nothing;
|
||||||
}
|
}
|
||||||
while (0);
|
while (0);
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
cat << EOF > expect
|
cat << EOF > expect
|
||||||
diff --git a/x b/x
|
diff --git a/x b/x
|
||||||
index adf3937..6edc172 100644
|
index adf3937..6edc172 100644
|
||||||
--- a/x
|
--- a/x
|
||||||
+++ b/x
|
+++ b/x
|
||||||
@@ -1,3 +1,5 @@
|
@@ -1,3 +1,5 @@
|
||||||
-do {
|
-do {
|
||||||
+do
|
+do
|
||||||
+{
|
+{
|
||||||
nothing;
|
nothing;
|
||||||
-} while (0);
|
-} while (0);
|
||||||
+}
|
+}
|
||||||
+while (0);
|
+while (0);
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
git diff > out
|
git diff > out
|
||||||
test_expect_success "Ray's example without options" 'test_cmp expect out'
|
test_expect_success "Ray's example without options" 'test_cmp expect out'
|
||||||
|
|
||||||
git diff -w > out
|
git diff -w > out
|
||||||
test_expect_success "Ray's example with -w" 'test_cmp expect out'
|
test_expect_success "Ray's example with -w" 'test_cmp expect out'
|
||||||
|
|
||||||
git diff -b > out
|
git diff -b > out
|
||||||
test_expect_success "Ray's example with -b" 'test_cmp expect out'
|
test_expect_success "Ray's example with -b" 'test_cmp expect out'
|
||||||
|
|
||||||
tr 'Q' '\015' << EOF > x
|
tr 'Q' '\015' << EOF > x
|
||||||
whitespace at beginning
|
whitespace at beginning
|
||||||
whitespace change
|
whitespace change
|
||||||
whitespace in the middle
|
whitespace in the middle
|
||||||
whitespace at end
|
whitespace at end
|
||||||
unchanged line
|
unchanged line
|
||||||
CR at endQ
|
CR at endQ
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
git update-index x
|
git update-index x
|
||||||
|
|
||||||
tr '_' ' ' << EOF > x
|
tr '_' ' ' << EOF > x
|
||||||
whitespace at beginning
|
whitespace at beginning
|
||||||
whitespace change
|
whitespace change
|
||||||
white space in the middle
|
white space in the middle
|
||||||
whitespace at end__
|
whitespace at end__
|
||||||
unchanged line
|
unchanged line
|
||||||
CR at end
|
CR at end
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
tr 'Q_' '\015 ' << EOF > expect
|
tr 'Q_' '\015 ' << EOF > expect
|
||||||
diff --git a/x b/x
|
diff --git a/x b/x
|
||||||
index d99af23..8b32fb5 100644
|
index d99af23..8b32fb5 100644
|
||||||
--- a/x
|
--- a/x
|
||||||
+++ b/x
|
+++ b/x
|
||||||
@@ -1,6 +1,6 @@
|
@@ -1,6 +1,6 @@
|
||||||
-whitespace at beginning
|
-whitespace at beginning
|
||||||
-whitespace change
|
-whitespace change
|
||||||
-whitespace in the middle
|
-whitespace in the middle
|
||||||
-whitespace at end
|
-whitespace at end
|
||||||
+ whitespace at beginning
|
+ whitespace at beginning
|
||||||
+whitespace change
|
+whitespace change
|
||||||
+white space in the middle
|
+white space in the middle
|
||||||
+whitespace at end__
|
+whitespace at end__
|
||||||
unchanged line
|
unchanged line
|
||||||
-CR at endQ
|
-CR at endQ
|
||||||
+CR at end
|
+CR at end
|
||||||
EOF
|
EOF
|
||||||
git diff > out
|
git diff > out
|
||||||
test_expect_success 'another test, without options' 'test_cmp expect out'
|
test_expect_success 'another test, without options' 'test_cmp expect out'
|
||||||
|
|
||||||
cat << EOF > expect
|
cat << EOF > expect
|
||||||
diff --git a/x b/x
|
diff --git a/x b/x
|
||||||
index d99af23..8b32fb5 100644
|
index d99af23..8b32fb5 100644
|
||||||
EOF
|
EOF
|
||||||
git diff -w > out
|
git diff -w > out
|
||||||
test_expect_success 'another test, with -w' 'test_cmp expect out'
|
test_expect_success 'another test, with -w' 'test_cmp expect out'
|
||||||
|
|
||||||
tr 'Q' '\015' << EOF > expect
|
tr 'Q' '\015' << EOF > expect
|
||||||
diff --git a/x b/x
|
diff --git a/x b/x
|
||||||
index d99af23..8b32fb5 100644
|
index d99af23..8b32fb5 100644
|
||||||
--- a/x
|
--- a/x
|
||||||
+++ b/x
|
+++ b/x
|
||||||
@@ -1,6 +1,6 @@
|
@@ -1,6 +1,6 @@
|
||||||
-whitespace at beginning
|
-whitespace at beginning
|
||||||
+ whitespace at beginning
|
+ whitespace at beginning
|
||||||
whitespace change
|
whitespace change
|
||||||
-whitespace in the middle
|
-whitespace in the middle
|
||||||
+white space in the middle
|
+white space in the middle
|
||||||
whitespace at end
|
whitespace at end
|
||||||
unchanged line
|
unchanged line
|
||||||
CR at endQ
|
CR at endQ
|
||||||
git diff -b --ignore-space-at-eol > out
|
git diff -b --ignore-space-at-eol > out
|
||||||
test_expect_failure 'another test, with -b --ignore-space-at-eol' 'test_cmp expect out'
|
test_expect_failure 'another test, with -b --ignore-space-at-eol' 'test_cmp expect out'
|
||||||
|
|
||||||
tr 'Q' '\015' << EOF > expect
|
tr 'Q' '\015' << EOF > expect
|
||||||
diff --git a/x b/x
|
diff --git a/x b/x
|
||||||
index d99af23..8b32fb5 100644
|
index d99af23..8b32fb5 100644
|
||||||
--- a/x
|
--- a/x
|
||||||
+++ b/x
|
+++ b/x
|
||||||
EOF
|
EOF
|
||||||
git diff -b > out
|
git diff -b > out
|
||||||
test_expect_success 'another test, with -b' 'test_cmp expect out'
|
test_expect_success 'another test, with -b' 'test_cmp expect out'
|
||||||
|
|
||||||
test_expect_success 'check mixed spaces and tabs in indent' '
|
test_expect_success 'check mixed spaces and tabs in indent' '
|
||||||
|
|
||||||
# This is indented with SP HT SP.
|
# This is indented with SP HT SP.
|
||||||
echo " foo();" > x &&
|
echo " foo();" > x &&
|
||||||
git diff --check | grep "space before tab in indent"
|
git diff --check | grep "space before tab in indent"
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check mixed tabs and spaces in indent' '
|
test_expect_success 'check mixed tabs and spaces in indent' '
|
||||||
|
|
||||||
# This is indented with HT SP HT.
|
# This is indented with HT SP HT.
|
||||||
echo " foo();" > x &&
|
echo " foo();" > x &&
|
||||||
git diff --check | grep "space before tab in indent"
|
git diff --check | grep "space before tab in indent"
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check with no whitespace errors' '
|
test_expect_success 'check with no whitespace errors' '
|
||||||
|
|
||||||
git commit -m "snapshot" &&
|
git commit -m "snapshot" &&
|
||||||
echo "foo();" > x &&
|
echo "foo();" > x &&
|
||||||
git diff --check
|
git diff --check
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check with trailing whitespace' '
|
test_expect_success 'check with trailing whitespace' '
|
||||||
|
|
||||||
echo "foo(); " > x &&
|
echo "foo(); " > x &&
|
||||||
test_must_fail git diff --check
|
test_must_fail git diff --check
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check with space before tab in indent' '
|
test_expect_success 'check with space before tab in indent' '
|
||||||
|
|
||||||
# indent has space followed by hard tab
|
# indent has space followed by hard tab
|
||||||
echo " foo();" > x &&
|
echo " foo();" > x &&
|
||||||
test_must_fail git diff --check
|
test_must_fail git diff --check
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success '--check and --exit-code are not exclusive' '
|
test_expect_success '--check and --exit-code are not exclusive' '
|
||||||
|
|
||||||
git checkout x &&
|
git checkout x &&
|
||||||
git diff --check --exit-code
|
git diff --check --exit-code
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success '--check and --quiet are not exclusive' '
|
test_expect_success '--check and --quiet are not exclusive' '
|
||||||
|
|
||||||
git diff --check --quiet
|
git diff --check --quiet
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check staged with no whitespace errors' '
|
test_expect_success 'check staged with no whitespace errors' '
|
||||||
|
|
||||||
echo "foo();" > x &&
|
echo "foo();" > x &&
|
||||||
git add x &&
|
git add x &&
|
||||||
git diff --cached --check
|
git diff --cached --check
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check staged with trailing whitespace' '
|
test_expect_success 'check staged with trailing whitespace' '
|
||||||
|
|
||||||
echo "foo(); " > x &&
|
echo "foo(); " > x &&
|
||||||
git add x &&
|
git add x &&
|
||||||
test_must_fail git diff --cached --check
|
test_must_fail git diff --cached --check
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check staged with space before tab in indent' '
|
test_expect_success 'check staged with space before tab in indent' '
|
||||||
|
|
||||||
# indent has space followed by hard tab
|
# indent has space followed by hard tab
|
||||||
echo " foo();" > x &&
|
echo " foo();" > x &&
|
||||||
git add x &&
|
git add x &&
|
||||||
test_must_fail git diff --cached --check
|
test_must_fail git diff --cached --check
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check with no whitespace errors (diff-index)' '
|
test_expect_success 'check with no whitespace errors (diff-index)' '
|
||||||
|
|
||||||
echo "foo();" > x &&
|
echo "foo();" > x &&
|
||||||
git add x &&
|
git add x &&
|
||||||
git diff-index --check HEAD
|
git diff-index --check HEAD
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check with trailing whitespace (diff-index)' '
|
test_expect_success 'check with trailing whitespace (diff-index)' '
|
||||||
|
|
||||||
echo "foo(); " > x &&
|
echo "foo(); " > x &&
|
||||||
git add x &&
|
git add x &&
|
||||||
test_must_fail git diff-index --check HEAD
|
test_must_fail git diff-index --check HEAD
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check with space before tab in indent (diff-index)' '
|
test_expect_success 'check with space before tab in indent (diff-index)' '
|
||||||
|
|
||||||
# indent has space followed by hard tab
|
# indent has space followed by hard tab
|
||||||
echo " foo();" > x &&
|
echo " foo();" > x &&
|
||||||
git add x &&
|
git add x &&
|
||||||
test_must_fail git diff-index --check HEAD
|
test_must_fail git diff-index --check HEAD
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check staged with no whitespace errors (diff-index)' '
|
test_expect_success 'check staged with no whitespace errors (diff-index)' '
|
||||||
|
|
||||||
echo "foo();" > x &&
|
echo "foo();" > x &&
|
||||||
git add x &&
|
git add x &&
|
||||||
git diff-index --cached --check HEAD
|
git diff-index --cached --check HEAD
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check staged with trailing whitespace (diff-index)' '
|
test_expect_success 'check staged with trailing whitespace (diff-index)' '
|
||||||
|
|
||||||
echo "foo(); " > x &&
|
echo "foo(); " > x &&
|
||||||
git add x &&
|
git add x &&
|
||||||
test_must_fail git diff-index --cached --check HEAD
|
test_must_fail git diff-index --cached --check HEAD
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check staged with space before tab in indent (diff-index)' '
|
test_expect_success 'check staged with space before tab in indent (diff-index)' '
|
||||||
|
|
||||||
# indent has space followed by hard tab
|
# indent has space followed by hard tab
|
||||||
echo " foo();" > x &&
|
echo " foo();" > x &&
|
||||||
git add x &&
|
git add x &&
|
||||||
test_must_fail git diff-index --cached --check HEAD
|
test_must_fail git diff-index --cached --check HEAD
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check with no whitespace errors (diff-tree)' '
|
test_expect_success 'check with no whitespace errors (diff-tree)' '
|
||||||
|
|
||||||
echo "foo();" > x &&
|
echo "foo();" > x &&
|
||||||
git commit -m "new commit" x &&
|
git commit -m "new commit" x &&
|
||||||
git diff-tree --check HEAD^ HEAD
|
git diff-tree --check HEAD^ HEAD
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check with trailing whitespace (diff-tree)' '
|
test_expect_success 'check with trailing whitespace (diff-tree)' '
|
||||||
|
|
||||||
echo "foo(); " > x &&
|
echo "foo(); " > x &&
|
||||||
git commit -m "another commit" x &&
|
git commit -m "another commit" x &&
|
||||||
test_must_fail git diff-tree --check HEAD^ HEAD
|
test_must_fail git diff-tree --check HEAD^ HEAD
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check with space before tab in indent (diff-tree)' '
|
test_expect_success 'check with space before tab in indent (diff-tree)' '
|
||||||
|
|
||||||
# indent has space followed by hard tab
|
# indent has space followed by hard tab
|
||||||
echo " foo();" > x &&
|
echo " foo();" > x &&
|
||||||
git commit -m "yet another" x &&
|
git commit -m "yet another" x &&
|
||||||
test_must_fail git diff-tree --check HEAD^ HEAD
|
test_must_fail git diff-tree --check HEAD^ HEAD
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check trailing whitespace (trailing-space: off)' '
|
test_expect_success 'check trailing whitespace (trailing-space: off)' '
|
||||||
|
|
||||||
git config core.whitespace "-trailing-space" &&
|
git config core.whitespace "-trailing-space" &&
|
||||||
echo "foo (); " > x &&
|
echo "foo (); " > x &&
|
||||||
git diff --check
|
git diff --check
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check trailing whitespace (trailing-space: on)' '
|
test_expect_success 'check trailing whitespace (trailing-space: on)' '
|
||||||
|
|
||||||
git config core.whitespace "trailing-space" &&
|
git config core.whitespace "trailing-space" &&
|
||||||
echo "foo (); " > x &&
|
echo "foo (); " > x &&
|
||||||
test_must_fail git diff --check
|
test_must_fail git diff --check
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check space before tab in indent (space-before-tab: off)' '
|
test_expect_success 'check space before tab in indent (space-before-tab: off)' '
|
||||||
|
|
||||||
# indent contains space followed by HT
|
# indent contains space followed by HT
|
||||||
git config core.whitespace "-space-before-tab" &&
|
git config core.whitespace "-space-before-tab" &&
|
||||||
echo " foo ();" > x &&
|
echo " foo ();" > x &&
|
||||||
git diff --check
|
git diff --check
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check space before tab in indent (space-before-tab: on)' '
|
test_expect_success 'check space before tab in indent (space-before-tab: on)' '
|
||||||
|
|
||||||
# indent contains space followed by HT
|
# indent contains space followed by HT
|
||||||
git config core.whitespace "space-before-tab" &&
|
git config core.whitespace "space-before-tab" &&
|
||||||
echo " foo (); " > x &&
|
echo " foo (); " > x &&
|
||||||
test_must_fail git diff --check
|
test_must_fail git diff --check
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check spaces as indentation (indent-with-non-tab: off)' '
|
test_expect_success 'check spaces as indentation (indent-with-non-tab: off)' '
|
||||||
|
|
||||||
git config core.whitespace "-indent-with-non-tab"
|
git config core.whitespace "-indent-with-non-tab"
|
||||||
echo " foo ();" > x &&
|
echo " foo ();" > x &&
|
||||||
git diff --check
|
git diff --check
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check spaces as indentation (indent-with-non-tab: on)' '
|
test_expect_success 'check spaces as indentation (indent-with-non-tab: on)' '
|
||||||
|
|
||||||
git config core.whitespace "indent-with-non-tab" &&
|
git config core.whitespace "indent-with-non-tab" &&
|
||||||
echo " foo ();" > x &&
|
echo " foo ();" > x &&
|
||||||
test_must_fail git diff --check
|
test_must_fail git diff --check
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'check tabs and spaces as indentation (indent-with-non-tab: on)' '
|
test_expect_success 'check tabs and spaces as indentation (indent-with-non-tab: on)' '
|
||||||
|
|
||||||
git config core.whitespace "indent-with-non-tab" &&
|
git config core.whitespace "indent-with-non-tab" &&
|
||||||
echo " foo ();" > x &&
|
echo " foo ();" > x &&
|
||||||
test_must_fail git diff --check
|
test_must_fail git diff --check
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'line numbers in --check output are correct' '
|
test_expect_success 'line numbers in --check output are correct' '
|
||||||
|
|
||||||
echo "" > x &&
|
echo "" > x &&
|
||||||
echo "foo(); " >> x &&
|
echo "foo(); " >> x &&
|
||||||
git diff --check | grep "x:2:"
|
git diff --check | grep "x:2:"
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'checkdiff detects trailing blank lines' '
|
test_expect_success 'checkdiff detects trailing blank lines' '
|
||||||
echo "foo();" >x &&
|
echo "foo();" >x &&
|
||||||
echo "" >>x &&
|
echo "" >>x &&
|
||||||
git diff --check | grep "ends with blank"
|
git diff --check | grep "ends with blank"
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'checkdiff allows new blank lines' '
|
test_expect_success 'checkdiff allows new blank lines' '
|
||||||
git checkout x &&
|
git checkout x &&
|
||||||
mv x y &&
|
mv x y &&
|
||||||
(
|
(
|
||||||
echo "/* This is new */" &&
|
echo "/* This is new */" &&
|
||||||
echo "" &&
|
echo "" &&
|
||||||
cat y
|
cat y
|
||||||
) >x &&
|
) >x &&
|
||||||
git diff --check
|
git diff --check
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'combined diff with autocrlf conversion' '
|
test_expect_success 'combined diff with autocrlf conversion' '
|
||||||
|
|
||||||
git reset --hard &&
|
git reset --hard &&
|
||||||
echo >x hello &&
|
echo >x hello &&
|
||||||
git commit -m "one side" x &&
|
git commit -m "one side" x &&
|
||||||
git checkout HEAD^ &&
|
git checkout HEAD^ &&
|
||||||
echo >x goodbye &&
|
echo >x goodbye &&
|
||||||
git commit -m "the other side" x &&
|
git commit -m "the other side" x &&
|
||||||
git config core.autocrlf true &&
|
git config core.autocrlf true &&
|
||||||
test_must_fail git merge master &&
|
test_must_fail git merge master &&
|
||||||
|
|
||||||
git diff | sed -e "1,/^@@@/d" >actual &&
|
git diff | sed -e "1,/^@@@/d" >actual &&
|
||||||
! grep "^-" actual
|
! grep "^-" actual
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
|
||||||
|
|
||||||
143
pom.xml
143
pom.xml
@@ -1,10 +1,15 @@
|
|||||||
<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/maven-v4_0_0.xsd">
|
<?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>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>io.github.java-diff-utils</groupId>
|
<groupId>io.github.java-diff-utils</groupId>
|
||||||
<artifactId>java-diff-utils</artifactId>
|
<artifactId>java-diff-utils-parent</artifactId>
|
||||||
<packaging>jar</packaging>
|
<version>4.4</version>
|
||||||
<version>4.0</version>
|
<name>java-diff-utils-parent</name>
|
||||||
<name>java-diff-utils</name>
|
<packaging>pom</packaging>
|
||||||
|
<modules>
|
||||||
|
<module>java-diff-utils</module>
|
||||||
|
<module>java-diff-utils-jgit</module>
|
||||||
|
</modules>
|
||||||
<description>The DiffUtils library for computing diffs, applying patches, generationg side-by-side view in Java.</description>
|
<description>The DiffUtils library for computing diffs, applying patches, generationg side-by-side view in Java.</description>
|
||||||
<url>https://github.com/java-diff-utils/java-diff-utils</url>
|
<url>https://github.com/java-diff-utils/java-diff-utils</url>
|
||||||
<inceptionYear>2009</inceptionYear>
|
<inceptionYear>2009</inceptionYear>
|
||||||
@@ -24,9 +29,8 @@
|
|||||||
<connection>scm:git:https://github.com/java-diff-utils/java-diff-utils.git</connection>
|
<connection>scm:git:https://github.com/java-diff-utils/java-diff-utils.git</connection>
|
||||||
<developerConnection>scm:git:ssh://git@github.com:java-diff-utils/java-diff-utils.git</developerConnection>
|
<developerConnection>scm:git:ssh://git@github.com:java-diff-utils/java-diff-utils.git</developerConnection>
|
||||||
<url>https://github.com/java-diff-utils/java-diff-utils.git</url>
|
<url>https://github.com/java-diff-utils/java-diff-utils.git</url>
|
||||||
<tag>java-diff-utils-4.0</tag>
|
<tag>java-diff-utils-parent-4.4</tag>
|
||||||
</scm>
|
</scm>
|
||||||
|
|
||||||
<issueManagement>
|
<issueManagement>
|
||||||
<system>GitHub Issues</system>
|
<system>GitHub Issues</system>
|
||||||
<url>https://github.com/java-diff-utils/java-diff-utils/issues</url>
|
<url>https://github.com/java-diff-utils/java-diff-utils/issues</url>
|
||||||
@@ -41,16 +45,6 @@
|
|||||||
<name>Tobias Warneke</name>
|
<name>Tobias Warneke</name>
|
||||||
<email>t.warneke@gmx.net</email>
|
<email>t.warneke@gmx.net</email>
|
||||||
</developer>
|
</developer>
|
||||||
<!--
|
|
||||||
<developer>
|
|
||||||
<name>Dmitry Naumenko</name>
|
|
||||||
<email>dm.naumenko@gmail.com</email>
|
|
||||||
</developer>
|
|
||||||
<developer>
|
|
||||||
<name>Juanco Anez</name>
|
|
||||||
<email>juanco@suigeneris.org</email>
|
|
||||||
</developer>
|
|
||||||
-->
|
|
||||||
</developers>
|
</developers>
|
||||||
|
|
||||||
<licenses>
|
<licenses>
|
||||||
@@ -61,81 +55,21 @@
|
|||||||
<comments>A business-friendly OSS license</comments>
|
<comments>A business-friendly OSS license</comments>
|
||||||
</license>
|
</license>
|
||||||
</licenses>
|
</licenses>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<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>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-release-plugin</artifactId>
|
||||||
<version>3.6.1</version>
|
<version>2.5.3</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<source>1.8</source>
|
<localCheckout>true</localCheckout>
|
||||||
<target>1.8</target>
|
<pushChanges>false</pushChanges>
|
||||||
<encoding>UTF-8</encoding>
|
<mavenExecutorId>forked-path</mavenExecutorId>
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
|
|
||||||
<!-- Make this JAR OSGi ready -->
|
|
||||||
<!-- We want to keep packaging type as jar. Therefore we need to customize the MANIFEST.MF.
|
|
||||||
See http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html
|
|
||||||
-->
|
|
||||||
<plugin>
|
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
|
||||||
<version>3.0.2</version>
|
|
||||||
<configuration>
|
|
||||||
<archive>
|
|
||||||
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
|
|
||||||
<manifestEntries>
|
|
||||||
<!-- identical to OSGI name -->
|
|
||||||
<Automatic-Module-Name>com.github.wumpz.diffutils</Automatic-Module-Name>
|
|
||||||
</manifestEntries>
|
|
||||||
</archive>
|
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
@@ -168,26 +102,6 @@
|
|||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
|
||||||
<version>2.19.1</version>
|
|
||||||
<configuration>
|
|
||||||
<excludes>
|
|
||||||
<exclude>**/LR*.java</exclude>
|
|
||||||
</excludes>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-release-plugin</artifactId>
|
|
||||||
<version>2.5.3</version>
|
|
||||||
<configuration>
|
|
||||||
<localCheckout>true</localCheckout>
|
|
||||||
<pushChanges>false</pushChanges>
|
|
||||||
<mavenExecutorId>forked-path</mavenExecutorId>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||||
@@ -209,12 +123,6 @@
|
|||||||
<module name="Checker">
|
<module name="Checker">
|
||||||
<module name="SuppressWarningsFilter" />
|
<module name="SuppressWarningsFilter" />
|
||||||
<module name="FileTabCharacter" />
|
<module name="FileTabCharacter" />
|
||||||
<!-- git checkout may change linefeeds on the fly
|
|
||||||
<module name="RegexpMultiline">
|
|
||||||
<property name="format" value="(?s:(\r\n|\r).*)" />
|
|
||||||
<property name="message" value="CRLF and CR line endings are prohibited, but this file uses them." />
|
|
||||||
</module>
|
|
||||||
-->
|
|
||||||
<module name="TreeWalker">
|
<module name="TreeWalker">
|
||||||
<module name="AvoidNestedBlocks" />
|
<module name="AvoidNestedBlocks" />
|
||||||
<module name="ConstantName" />
|
<module name="ConstantName" />
|
||||||
@@ -243,10 +151,20 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.puppycrawl.tools</groupId>
|
<groupId>com.puppycrawl.tools</groupId>
|
||||||
<artifactId>checkstyle</artifactId>
|
<artifactId>checkstyle</artifactId>
|
||||||
<version>6.19</version>
|
<version>8.18</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>2.22.1</version>
|
||||||
|
<configuration>
|
||||||
|
<excludes>
|
||||||
|
<exclude>**/LR*.java</exclude>
|
||||||
|
</excludes>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
<profiles>
|
<profiles>
|
||||||
@@ -306,5 +224,4 @@
|
|||||||
</build>
|
</build>
|
||||||
</profile>
|
</profile>
|
||||||
</profiles>
|
</profiles>
|
||||||
</project>
|
</project>
|
||||||
|
|
||||||
Reference in New Issue
Block a user