use of org.eclipse.jgit.diff.Edit in project gerrit by GerritCodeReview.
the class IntraLineLoader method combineLineEdits.
private static void combineLineEdits(List<Edit> edits, Text a, Text b) {
for (int j = 0; j < edits.size() - 1; ) {
Edit c = edits.get(j);
Edit n = edits.get(j + 1);
// Combine edits that are really close together. Right now our rule
// is, coalesce two line edits which are only one line apart if that
// common context line is either a "pointless line", or is identical
// on both sides and starts a new block of code. These are mostly
// block reindents to add or remove control flow operators.
//
final int ad = n.getBeginA() - c.getEndA();
final int bd = n.getBeginB() - c.getEndB();
if ((1 <= ad && isBlankLineGap(a, c.getEndA(), n.getBeginA())) || (1 <= bd && isBlankLineGap(b, c.getEndB(), n.getBeginB())) || (ad == 1 && bd == 1 && isControlBlockStart(a, c.getEndA()))) {
int ab = c.getBeginA();
int ae = n.getEndA();
int bb = c.getBeginB();
int be = n.getEndB();
edits.set(j, new Edit(ab, ae, bb, be));
edits.remove(j + 1);
continue;
}
j++;
}
}
use of org.eclipse.jgit.diff.Edit in project gerrit by GerritCodeReview.
the class IntraLineLoader method compute.
static IntraLineDiff compute(Text aText, Text bText, ImmutableList<Edit> immutableEdits) throws Exception {
List<Edit> edits = new ArrayList<>(immutableEdits);
combineLineEdits(edits, aText, bText);
for (int i = 0; i < edits.size(); i++) {
Edit e = edits.get(i);
if (e.getType() == Edit.Type.REPLACE) {
CharText a = new CharText(aText, e.getBeginA(), e.getEndA());
CharText b = new CharText(bText, e.getBeginB(), e.getEndB());
CharTextComparator cmp = new CharTextComparator();
List<Edit> wordEdits = MyersDiff.INSTANCE.diff(cmp, a, b);
//
for (int j = 0; j < wordEdits.size() - 1; ) {
Edit c = wordEdits.get(j);
Edit n = wordEdits.get(j + 1);
if (n.getBeginA() - c.getEndA() <= 5 || n.getBeginB() - c.getEndB() <= 5) {
int ab = c.getBeginA();
int ae = n.getEndA();
int bb = c.getBeginB();
int be = n.getEndB();
if (canCoalesce(a, c.getEndA(), n.getBeginA()) && canCoalesce(b, c.getEndB(), n.getBeginB())) {
wordEdits.set(j, new Edit(ab, ae, bb, be));
wordEdits.remove(j + 1);
continue;
}
}
j++;
}
//
for (int j = 0; j < wordEdits.size(); j++) {
Edit c = wordEdits.get(j);
int ab = c.getBeginA();
int ae = c.getEndA();
int bb = c.getBeginB();
int be = c.getEndB();
//
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);
}
}
//
while (ab < ae && bb < be && cmp.equals(a, ab, b, bb)) {
ab++;
bb++;
}
while (ab < ae && bb < be && cmp.equals(a, ae - 1, b, be - 1)) {
ae--;
be--;
}
//
while (0 < ab && ab < ae && a.charAt(ab - 1) != '\n' && cmp.equals(a, ab - 1, a, ae - 1)) {
ab--;
ae--;
}
if (!a.isLineStart(ab) || !a.contains(ab, ae, '\n')) {
while (ab < ae && ae < a.size() && cmp.equals(a, ab, a, ae)) {
ab++;
ae++;
if (a.charAt(ae - 1) == '\n') {
break;
}
}
}
while (0 < bb && bb < be && b.charAt(bb - 1) != '\n' && cmp.equals(b, bb - 1, b, be - 1)) {
bb--;
be--;
}
if (!b.isLineStart(bb) || !b.contains(bb, be, '\n')) {
while (bb < be && be < b.size() && cmp.equals(b, bb, b, be)) {
bb++;
be++;
if (b.charAt(be - 1) == '\n') {
break;
}
}
}
//
if (//
ab < ae && //
(ab == 0 || a.charAt(ab - 1) == '\n') && ae < a.size() && a.charAt(ae - 1) != '\n' && a.charAt(ae) == '\n') {
ae++;
}
if (//
bb < be && //
(bb == 0 || b.charAt(bb - 1) == '\n') && be < b.size() && b.charAt(be - 1) != '\n' && b.charAt(be) == '\n') {
be++;
}
wordEdits.set(j, new Edit(ab, ae, bb, be));
}
edits.set(i, new ReplaceEdit(e, wordEdits));
}
}
return new IntraLineDiff(edits);
}
use of org.eclipse.jgit.diff.Edit in project gerrit by GerritCodeReview.
the class PatchScriptBuilder method build.
private PatchScript build(final PatchListEntry content, final CommentDetail comments, final List<Patch> history) throws IOException {
boolean intralineDifferenceIsPossible = true;
boolean intralineFailure = false;
boolean intralineTimeout = false;
a.path = oldName(content);
b.path = newName(content);
a.resolve(null, aId);
b.resolve(a, bId);
edits = new ArrayList<>(content.getEdits());
if (!isModify(content)) {
intralineDifferenceIsPossible = false;
} else if (diffPrefs.intralineDifference) {
IntraLineDiff d = patchListCache.getIntraLineDiff(IntraLineDiffKey.create(a.id, b.id, diffPrefs.ignoreWhitespace), IntraLineDiffArgs.create(a.src, b.src, edits, projectKey, bId, b.path));
if (d != null) {
switch(d.getStatus()) {
case EDIT_LIST:
edits = new ArrayList<>(d.getEdits());
break;
case DISABLED:
intralineDifferenceIsPossible = false;
break;
case ERROR:
intralineDifferenceIsPossible = false;
intralineFailure = true;
break;
case TIMEOUT:
intralineDifferenceIsPossible = false;
intralineTimeout = true;
break;
}
} else {
intralineDifferenceIsPossible = false;
intralineFailure = true;
}
}
if (comments != null) {
ensureCommentsVisible(comments);
}
boolean hugeFile = false;
if (a.src == b.src && a.size() <= context && content.getEdits().isEmpty()) {
//
for (int i = 0; i < a.size(); i++) {
a.addLine(i);
}
edits = new ArrayList<>(1);
edits.add(new Edit(a.size(), a.size()));
} else {
if (BIG_FILE < Math.max(a.size(), b.size())) {
// IF the file is really large, we disable things to avoid choking
// the browser client.
//
hugeFile = true;
}
// In order to expand the skipped common lines or syntax highlight the
// file properly we need to give the client the complete file contents.
// So force our context temporarily to the complete file size.
//
context = MAX_CONTEXT;
packContent(diffPrefs.ignoreWhitespace != Whitespace.IGNORE_NONE);
}
return new PatchScript(change.getKey(), content.getChangeType(), content.getOldName(), content.getNewName(), a.fileMode, b.fileMode, content.getHeaderLines(), diffPrefs, a.dst, b.dst, edits, a.displayMethod, b.displayMethod, a.mimeType.toString(), b.mimeType.toString(), comments, history, hugeFile, intralineDifferenceIsPossible, intralineFailure, intralineTimeout, content.getPatchType() == Patch.PatchType.BINARY, aId == null ? null : aId.getName(), bId == null ? null : bId.getName());
}
use of org.eclipse.jgit.diff.Edit in project gerrit by GerritCodeReview.
the class PatchListEntry method writeTo.
void writeTo(OutputStream out) throws IOException {
writeEnum(out, changeType);
writeEnum(out, patchType);
writeString(out, oldName);
writeString(out, newName);
writeBytes(out, header);
writeVarInt32(out, insertions);
writeVarInt32(out, deletions);
writeFixInt64(out, size);
writeFixInt64(out, sizeDelta);
writeVarInt32(out, edits.size());
for (final Edit e : edits) {
writeVarInt32(out, e.getBeginA());
writeVarInt32(out, e.getEndA());
writeVarInt32(out, e.getBeginB());
writeVarInt32(out, e.getEndB());
}
}
use of org.eclipse.jgit.diff.Edit in project gerrit by GerritCodeReview.
the class EditList method combineA.
private boolean combineA(final int i) {
final Edit s = edits.get(i);
final Edit e = edits.get(i - 1);
// + 1 to prevent '... skipping 1 common line ...' messages.
return s.getBeginA() - e.getEndA() <= 2 * context + 1;
}
Aggregations