Search in sources :

Example 1 with ReplaceEdit

use of org.eclipse.jgit.diff.ReplaceEdit in project gerrit by GerritCodeReview.

the class IntraLineDiff method writeObject.

private void writeObject(final ObjectOutputStream out) throws IOException {
    writeEnum(out, status);
    writeVarInt32(out, edits.size());
    for (Edit e : edits) {
        writeEdit(out, e);
        if (e instanceof ReplaceEdit) {
            ReplaceEdit r = (ReplaceEdit) e;
            writeVarInt32(out, r.getInternalEdits().size());
            for (Edit i : r.getInternalEdits()) {
                writeEdit(out, i);
            }
        } else {
            writeVarInt32(out, 0);
        }
    }
}
Also used : ReplaceEdit(org.eclipse.jgit.diff.ReplaceEdit) ReplaceEdit(org.eclipse.jgit.diff.ReplaceEdit) Edit(org.eclipse.jgit.diff.Edit)

Example 2 with ReplaceEdit

use of org.eclipse.jgit.diff.ReplaceEdit 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);
}
Also used : ArrayList(java.util.ArrayList) ReplaceEdit(org.eclipse.jgit.diff.ReplaceEdit) ReplaceEdit(org.eclipse.jgit.diff.ReplaceEdit) Edit(org.eclipse.jgit.diff.Edit)

Example 3 with ReplaceEdit

use of org.eclipse.jgit.diff.ReplaceEdit in project gerrit by GerritCodeReview.

the class IntraLineLoaderTest method intraline.

private static List<Edit> intraline(String a, String b, Edit lines) throws Exception {
    Text aText = new Text(a.getBytes(UTF_8));
    Text bText = new Text(b.getBytes(UTF_8));
    IntraLineDiff diff = IntraLineLoader.compute(aText, bText, ImmutableList.of(lines));
    assertThat(diff.getStatus()).isEqualTo(IntraLineDiff.Status.EDIT_LIST);
    List<Edit> actualEdits = diff.getEdits();
    assertThat(actualEdits).hasSize(1);
    Edit actualEdit = actualEdits.get(0);
    assertThat(actualEdit.getBeginA()).isEqualTo(lines.getBeginA());
    assertThat(actualEdit.getEndA()).isEqualTo(lines.getEndA());
    assertThat(actualEdit.getBeginB()).isEqualTo(lines.getBeginB());
    assertThat(actualEdit.getEndB()).isEqualTo(lines.getEndB());
    assertThat(actualEdit).isInstanceOf(ReplaceEdit.class);
    return ((ReplaceEdit) actualEdit).getInternalEdits();
}
Also used : ReplaceEdit(org.eclipse.jgit.diff.ReplaceEdit) ReplaceEdit(org.eclipse.jgit.diff.ReplaceEdit) Edit(org.eclipse.jgit.diff.Edit)

Example 4 with ReplaceEdit

use of org.eclipse.jgit.diff.ReplaceEdit in project gerrit by GerritCodeReview.

the class GetDiff method apply.

@Override
public Response<DiffInfo> apply(FileResource resource) throws ResourceConflictException, ResourceNotFoundException, OrmException, AuthException, InvalidChangeOperationException, IOException {
    DiffPreferencesInfo prefs = new DiffPreferencesInfo();
    if (whitespace != null) {
        prefs.ignoreWhitespace = whitespace;
    } else if (ignoreWhitespace != null) {
        prefs.ignoreWhitespace = ignoreWhitespace.whitespace;
    } else {
        prefs.ignoreWhitespace = Whitespace.IGNORE_LEADING_AND_TRAILING;
    }
    prefs.context = context;
    prefs.intralineDifference = intraline;
    PatchScriptFactory psf;
    PatchSet basePatchSet = null;
    if (base != null) {
        RevisionResource baseResource = revisions.parse(resource.getRevision().getChangeResource(), IdString.fromDecoded(base));
        basePatchSet = baseResource.getPatchSet();
        psf = patchScriptFactoryFactory.create(resource.getRevision().getControl(), resource.getPatchKey().getFileName(), basePatchSet.getId(), resource.getPatchKey().getParentKey(), prefs);
    } else if (parentNum > 0) {
        psf = patchScriptFactoryFactory.create(resource.getRevision().getControl(), resource.getPatchKey().getFileName(), parentNum - 1, resource.getPatchKey().getParentKey(), prefs);
    } else {
        psf = patchScriptFactoryFactory.create(resource.getRevision().getControl(), resource.getPatchKey().getFileName(), null, resource.getPatchKey().getParentKey(), prefs);
    }
    try {
        psf.setLoadHistory(false);
        psf.setLoadComments(context != DiffPreferencesInfo.WHOLE_FILE_CONTEXT);
        PatchScript ps = psf.call();
        Content content = new Content(ps);
        for (Edit edit : ps.getEdits()) {
            if (edit.getType() == Edit.Type.EMPTY) {
                continue;
            }
            content.addCommon(edit.getBeginA());
            checkState(content.nextA == edit.getBeginA(), "nextA = %s; want %s", content.nextA, edit.getBeginA());
            checkState(content.nextB == edit.getBeginB(), "nextB = %s; want %s", content.nextB, edit.getBeginB());
            switch(edit.getType()) {
                case DELETE:
                case INSERT:
                case REPLACE:
                    List<Edit> internalEdit = edit instanceof ReplaceEdit ? ((ReplaceEdit) edit).getInternalEdits() : null;
                    content.addDiff(edit.getEndA(), edit.getEndB(), internalEdit);
                    break;
                case EMPTY:
                default:
                    throw new IllegalStateException();
            }
        }
        content.addCommon(ps.getA().size());
        ProjectState state = projectCache.get(resource.getRevision().getChange().getProject());
        DiffInfo result = new DiffInfo();
        // TODO referring to the parent commit by refs/changes/12/60012/1^1
        // will likely not work for inline edits
        String revA = basePatchSet != null ? basePatchSet.getRefName() : resource.getRevision().getPatchSet().getRefName() + "^1";
        String revB = resource.getRevision().getEdit().isPresent() ? resource.getRevision().getEdit().get().getRefName() : resource.getRevision().getPatchSet().getRefName();
        List<DiffWebLinkInfo> links = webLinks.getDiffLinks(state.getProject().getName(), resource.getPatchKey().getParentKey().getParentKey().get(), basePatchSet != null ? basePatchSet.getId().get() : null, revA, MoreObjects.firstNonNull(ps.getOldName(), ps.getNewName()), resource.getPatchKey().getParentKey().get(), revB, ps.getNewName());
        result.webLinks = links.isEmpty() ? null : links;
        if (!webLinksOnly) {
            if (ps.isBinary()) {
                result.binary = true;
            }
            if (ps.getDisplayMethodA() != DisplayMethod.NONE) {
                result.metaA = new FileMeta();
                result.metaA.name = MoreObjects.firstNonNull(ps.getOldName(), ps.getNewName());
                result.metaA.contentType = FileContentUtil.resolveContentType(state, result.metaA.name, ps.getFileModeA(), ps.getMimeTypeA());
                result.metaA.lines = ps.getA().size();
                result.metaA.webLinks = getFileWebLinks(state.getProject(), revA, result.metaA.name);
                result.metaA.commitId = content.commitIdA;
            }
            if (ps.getDisplayMethodB() != DisplayMethod.NONE) {
                result.metaB = new FileMeta();
                result.metaB.name = ps.getNewName();
                result.metaB.contentType = FileContentUtil.resolveContentType(state, result.metaB.name, ps.getFileModeB(), ps.getMimeTypeB());
                result.metaB.lines = ps.getB().size();
                result.metaB.webLinks = getFileWebLinks(state.getProject(), revB, result.metaB.name);
                result.metaB.commitId = content.commitIdB;
            }
            if (intraline) {
                if (ps.hasIntralineTimeout()) {
                    result.intralineStatus = IntraLineStatus.TIMEOUT;
                } else if (ps.hasIntralineFailure()) {
                    result.intralineStatus = IntraLineStatus.FAILURE;
                } else {
                    result.intralineStatus = IntraLineStatus.OK;
                }
            }
            result.changeType = CHANGE_TYPE.get(ps.getChangeType());
            if (result.changeType == null) {
                throw new IllegalStateException("unknown change type: " + ps.getChangeType());
            }
            if (ps.getPatchHeader().size() > 0) {
                result.diffHeader = ps.getPatchHeader();
            }
            result.content = content.lines;
        }
        Response<DiffInfo> r = Response.ok(result);
        if (resource.isCacheable()) {
            r.caching(CacheControl.PRIVATE(7, TimeUnit.DAYS));
        }
        return r;
    } catch (NoSuchChangeException e) {
        throw new ResourceNotFoundException(e.getMessage(), e);
    } catch (LargeObjectException e) {
        throw new ResourceConflictException(e.getMessage(), e);
    }
}
Also used : PatchScript(com.google.gerrit.common.data.PatchScript) PatchSet(com.google.gerrit.reviewdb.client.PatchSet) ReplaceEdit(org.eclipse.jgit.diff.ReplaceEdit) Edit(org.eclipse.jgit.diff.Edit) IdString(com.google.gerrit.extensions.restapi.IdString) LargeObjectException(com.google.gerrit.server.git.LargeObjectException) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) DiffWebLinkInfo(com.google.gerrit.extensions.common.DiffWebLinkInfo) NoSuchChangeException(com.google.gerrit.server.project.NoSuchChangeException) PatchScriptFactory(com.google.gerrit.server.patch.PatchScriptFactory) SparseFileContent(com.google.gerrit.prettify.common.SparseFileContent) ReplaceEdit(org.eclipse.jgit.diff.ReplaceEdit) ProjectState(com.google.gerrit.server.project.ProjectState) ResourceNotFoundException(com.google.gerrit.extensions.restapi.ResourceNotFoundException) DiffPreferencesInfo(com.google.gerrit.extensions.client.DiffPreferencesInfo) FileMeta(com.google.gerrit.extensions.common.DiffInfo.FileMeta) DiffInfo(com.google.gerrit.extensions.common.DiffInfo)

Example 5 with ReplaceEdit

use of org.eclipse.jgit.diff.ReplaceEdit in project gerrit by GerritCodeReview.

the class IntraLineDiff method readObject.

private void readObject(final ObjectInputStream in) throws IOException {
    status = readEnum(in, Status.values());
    int editCount = readVarInt32(in);
    Edit[] editArray = new Edit[editCount];
    for (int i = 0; i < editCount; i++) {
        editArray[i] = readEdit(in);
        int innerCount = readVarInt32(in);
        if (0 < innerCount) {
            Edit[] inner = new Edit[innerCount];
            for (int j = 0; j < innerCount; j++) {
                inner[j] = readEdit(in);
            }
            editArray[i] = new ReplaceEdit(editArray[i], toList(inner));
        }
    }
    edits = ImmutableList.copyOf(editArray);
}
Also used : ReplaceEdit(org.eclipse.jgit.diff.ReplaceEdit) ReplaceEdit(org.eclipse.jgit.diff.ReplaceEdit) Edit(org.eclipse.jgit.diff.Edit)

Aggregations

Edit (org.eclipse.jgit.diff.Edit)5 ReplaceEdit (org.eclipse.jgit.diff.ReplaceEdit)5 PatchScript (com.google.gerrit.common.data.PatchScript)1 DiffPreferencesInfo (com.google.gerrit.extensions.client.DiffPreferencesInfo)1 DiffInfo (com.google.gerrit.extensions.common.DiffInfo)1 FileMeta (com.google.gerrit.extensions.common.DiffInfo.FileMeta)1 DiffWebLinkInfo (com.google.gerrit.extensions.common.DiffWebLinkInfo)1 IdString (com.google.gerrit.extensions.restapi.IdString)1 ResourceConflictException (com.google.gerrit.extensions.restapi.ResourceConflictException)1 ResourceNotFoundException (com.google.gerrit.extensions.restapi.ResourceNotFoundException)1 SparseFileContent (com.google.gerrit.prettify.common.SparseFileContent)1 PatchSet (com.google.gerrit.reviewdb.client.PatchSet)1 LargeObjectException (com.google.gerrit.server.git.LargeObjectException)1 PatchScriptFactory (com.google.gerrit.server.patch.PatchScriptFactory)1 NoSuchChangeException (com.google.gerrit.server.project.NoSuchChangeException)1 ProjectState (com.google.gerrit.server.project.ProjectState)1 ArrayList (java.util.ArrayList)1