Skip to content

Get list of lines that are common between source and patch #42

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
xbotuk opened this issue May 14, 2019 · 9 comments
Closed

Get list of lines that are common between source and patch #42

xbotuk opened this issue May 14, 2019 · 9 comments

Comments

@xbotuk
Copy link

xbotuk commented May 14, 2019

I am trying to iterate through the deltas =, however I would like to get list of lines that are common between the two sets of List by checking
if (delta.getType() == DeltaType.EQUAL) {
}

However I am not able to see how to get this. The JUnit code and test examples do not show this examples. Please help?

@wumpz
Copy link
Collaborator

wumpz commented May 14, 2019

The deltas are always differences. But they are ordered and within the Patch instance you have line numbers from source and target. Therefore all line numbers not covered by diffs are equal.

@cowwoc
Copy link
Contributor

cowwoc commented Mar 27, 2020

@wumpz Coming from https://github.com/google/diff-match-patch I also find this very annoying. I'd like the list returned by DiffUtils.diff() to contain EqualDelta entries that would look something like this:

public final class EqualDelta<T> extends AbstractDelta<T>
{
	/**
	 * Creates an insert delta with the two given chunks.
	 *
	 * @param original The original chunk. Must not be {@code null}.
	 * @param revised  The original chunk. Must not be {@code null}.
	 */
	public EqualDelta(Chunk<T> original, Chunk<T> revised)
	{
		super(DeltaType.EQUAL, original, revised);
	}

	@Override
	public void applyTo(List<T> target) throws PatchFailedException
	{
		verifyChunk(target);
	}

	@Override
	public void restore(List<T> target)
	{
	}

	@Override
	public String toString()
	{
		return "[EqualDelta, source.position: " + getSource().getPosition() + ", target.position: " +
			getTarget().getPosition() + ", lines: " + getSource().getLines() + "]";
	}
}

Applying these deltas would do nothing, but anything iterating through the list of deltas will have a much easier time figuring out the span of equal regions.

@wumpz
Copy link
Collaborator

wumpz commented Mar 28, 2020

Let me take a look into this. May be integrate this optioinal?

@wumpz wumpz pinned this issue Apr 10, 2020
@wumpz
Copy link
Collaborator

wumpz commented Apr 18, 2020

I started the first version in 4.7-SNAPSHOT. This is an additional parameter to the diff methods for generating equal parts. I was thinking to do it afterwards, but generating it right within the Patch seemed the cleanest way to do it.

@wumpz
Copy link
Collaborator

wumpz commented Apr 18, 2020

@cowwoc Could you check if this is what you want?

DiffUtils.diff(orig, revised, true) -> last parameter for include equal parts.

@cowwoc
Copy link
Contributor

cowwoc commented Apr 19, 2020

@wumpz No, something is wrong. I am getting back the wrong deltas.

I compare:

The dog is brown to
The fox is down

If I add equals deltas myself, I get back the following deltas:

EQUALS: "The"
DELETE: "d"
INSERT: "f"
EQUAL: "o"
DELETE: "g"
INSERT: "x"
EQUAL: " is "
DELETE: "br"
INSERT: "d"
EQUAL: "own"

When I use your mechanism, I get:

EQUAL: "The dog is "
DELETE: "d"
INSERT: "f"
EQUAL: "o"
DELETE: "g"
INSERT: "x"
EQUAL: " g is brown"
DELETE: "br"
INSERT: "d"

Please double-check this on your end.

@cowwoc
Copy link
Contributor

cowwoc commented Apr 19, 2020

Here is the code I used to add EQUALS after-the-fact:

/**
 * Adds EqualDelta entries (not added by DiffUtils.diff()).
 *
 * @param <T>    the type of elements in the lists
 * @param deltas the list of deltas
 * @param source the source list
 * @param target the target list
 * @return the updated list
 */
private <T> List<AbstractDelta<T>> addEqualDeltas(List<AbstractDelta<T>> deltas, List<T> source,
						  List<T> target)
{
	// WORKAROUND: https://github.com/java-diff-utils/java-diff-utils/issues/42
	List<AbstractDelta<T>> result = new ArrayList<>();
	int sourceStartPosition = 0;
	int targetStartPosition = 0;
	for (AbstractDelta<T> delta : deltas)
	{
		int sourceEndPosition = delta.getSource().getPosition();
		int targetEndPosition = delta.getTarget().getPosition();
		if (sourceStartPosition < sourceEndPosition || targetStartPosition < targetEndPosition)
		{
			// The gaps between deltas denote equal chunks
			result.add(new EqualDelta<>(
				new Chunk<>(sourceStartPosition, source.subList(sourceStartPosition, sourceEndPosition)),
				new Chunk<>(targetStartPosition, target.subList(targetStartPosition, targetEndPosition))));
		}
		sourceStartPosition = delta.getSource().last() + 1;
		targetStartPosition = delta.getTarget().last() + 1;
		result.add(delta);
	}
	// Add final chunk, if necessary.
	if (sourceStartPosition < source.size() || targetStartPosition < target.size())
	{
		// Deltas do not contain equal chunks. We need to derive those ourselves.
		result.add(new EqualDelta<>(
			new Chunk<>(sourceStartPosition, source.subList(sourceStartPosition, source.size())),
			new Chunk<>(targetStartPosition, target.subList(targetStartPosition, target.size()))));
	}
	return result;
}

@wumpz
Copy link
Collaborator

wumpz commented Apr 19, 2020

The problem is corrected. Depending on what diff algorithm you use, the list of changes is delivered in a different order. That was the main problem.

@cowwoc
Copy link
Contributor

cowwoc commented Apr 20, 2020

@wumpz Confirmed. The bug is fixed and I consider this issue resolved.

Are we able to move forward with #75 as well? Once these two are completed, I'd like to request a new release so I can have my library to use it.

@wumpz wumpz closed this as completed Apr 20, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants