Avoid "es" replaced by "es = Address"
In some crazy cases the diff engine can select an odd delta which causes us to present a pointless replace to the end-user. Consider the patch: -Address[] replyToAddresses; +Address[] replyToAddresses = Address.unpack(list); The MyersDiff engine anchored the second occurrence of "Address" in the preimage with the third occurrence in the postimage. We are thus seeing the engine suggest an insert of the word "Address" between the "o" and the "A" in the left side, and in a later edit it supplied a replace of "es" with ".unpack(list)". Previously we wound up showing the user that "es" was replaced by the string "es = Address.unpack(list)". By trying to join edits a second time after the context shifting, and this time using only edits that are strictly consecutive, we can see enough of the region at once to shift it down and get the real delta, which is that insert. This sort of scrubbing rule probably should go back into the MyersDiff engine, or a wrapper around it in JGit. But given how slow JGit is right now at picking up patches I'm keeping it here in Gerrit Code Review until the upstream MyersDiff can be tuned a bit better for this case. Change-Id: I86d84b7b8b8dad6a537653f5239b99232eac018c Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
@@ -286,6 +286,26 @@ public class PatchListCacheImpl implements PatchListCache {
|
||||
int bb = c.getBeginB();
|
||||
int be = c.getEndB();
|
||||
|
||||
// Sometimes the diff generator produces an INSERT or DELETE
|
||||
// right up against a REPLACE, but we only find this after
|
||||
// we've also played some shifting games on the prior edit.
|
||||
// If that happened to us, coalesce them together so we can
|
||||
// correct this mess for the user. If we don't we wind up
|
||||
// with silly stuff like "es" -> "es = Addresses".
|
||||
//
|
||||
if (1 < j) {
|
||||
Edit p = wordEdits.get(j - 1);
|
||||
if (p.getEndA() == ab || p.getEndB() == bb) {
|
||||
if (p.getEndA() == ab && p.getBeginA() < p.getEndA()) {
|
||||
ab = p.getBeginA();
|
||||
}
|
||||
if (p.getEndB() == bb && p.getBeginB() < p.getEndB()) {
|
||||
bb = p.getBeginB();
|
||||
}
|
||||
wordEdits.remove(--j);
|
||||
}
|
||||
}
|
||||
|
||||
// We sometimes collapsed an edit together in a strange way,
|
||||
// such that the edges of each text is identical. Fix by
|
||||
// by dropping out that incorrectly replaced region.
|
||||
|
||||
Reference in New Issue
Block a user