Search in sources :

Example 1 with DiffNotAvailableException

use of com.google.gerrit.server.patch.DiffNotAvailableException in project gerrit by GerritCodeReview.

the class AllDiffsEvaluator method execute.

Map<AugmentedFileDiffCacheKey, AllFileGitDiffs> execute(List<AugmentedFileDiffCacheKey> augmentedKeys) throws DiffNotAvailableException {
    ImmutableMap.Builder<AugmentedFileDiffCacheKey, AllFileGitDiffs> keyToAllDiffs = ImmutableMap.builderWithExpectedSize(augmentedKeys.size());
    List<AugmentedFileDiffCacheKey> keysWithRebaseEdits = augmentedKeys.stream().filter(k -> !k.ignoreRebase()).collect(Collectors.toList());
    // TODO(ghareeb): as an enhancement, you can batch these calls as follows.
    // First batch: "old commit vs. new commit" and "new parent vs. new commit"
    // Second batch: "old parent vs. old commit" and "old parent vs. new parent"
    Map<FileDiffCacheKey, GitDiffEntity> mainDiffs = computeGitFileDiffs(createGitKeys(augmentedKeys, k -> k.key().oldCommit(), k -> k.key().newCommit(), k -> k.key().newFilePath()));
    Map<FileDiffCacheKey, GitDiffEntity> oldVsParentDiffs = computeGitFileDiffs(createGitKeys(keysWithRebaseEdits, // oldParent is set for keysWithRebaseEdits
    k -> k.oldParentId().get(), k -> k.key().oldCommit(), k -> mainDiffs.get(k.key()).gitDiff().oldPath().orElse(null)));
    Map<FileDiffCacheKey, GitDiffEntity> newVsParentDiffs = computeGitFileDiffs(createGitKeys(keysWithRebaseEdits, // newParent is set for keysWithRebaseEdits
    k -> k.newParentId().get(), k -> k.key().newCommit(), k -> k.key().newFilePath()));
    Map<FileDiffCacheKey, GitDiffEntity> parentsDiffs = computeGitFileDiffs(createGitKeys(keysWithRebaseEdits, k -> k.oldParentId().get(), k -> k.newParentId().get(), k -> {
        GitFileDiff newVsParDiff = newVsParentDiffs.get(k.key()).gitDiff();
        // the first situation described?
        return newVsParDiff.oldPath().orElse(k.key().newFilePath());
    }));
    for (AugmentedFileDiffCacheKey augmentedKey : augmentedKeys) {
        FileDiffCacheKey key = augmentedKey.key();
        AllFileGitDiffs.Builder builder = AllFileGitDiffs.builder().augmentedKey(augmentedKey).mainDiff(mainDiffs.get(key));
        if (augmentedKey.ignoreRebase()) {
            keyToAllDiffs.put(augmentedKey, builder.build());
            continue;
        }
        if (oldVsParentDiffs.containsKey(key) && !oldVsParentDiffs.get(key).gitDiff().isEmpty()) {
            builder.oldVsParentDiff(Optional.of(oldVsParentDiffs.get(key)));
        }
        if (newVsParentDiffs.containsKey(key) && !newVsParentDiffs.get(key).gitDiff().isEmpty()) {
            builder.newVsParentDiff(Optional.of(newVsParentDiffs.get(key)));
        }
        if (parentsDiffs.containsKey(key) && !parentsDiffs.get(key).gitDiff().isEmpty()) {
            builder.parentVsParentDiff(Optional.of(parentsDiffs.get(key)));
        }
        keyToAllDiffs.put(augmentedKey, builder.build());
    }
    return keyToAllDiffs.build();
}
Also used : GitFileDiffCacheKey(com.google.gerrit.server.patch.gitfilediff.GitFileDiffCacheKey) GitFileDiffCache(com.google.gerrit.server.patch.gitfilediff.GitFileDiffCache) ImmutableMap(com.google.common.collect.ImmutableMap) Inject(com.google.inject.Inject) IOException(java.io.IOException) HashMap(java.util.HashMap) Function(java.util.function.Function) Collectors(java.util.stream.Collectors) ObjectId(org.eclipse.jgit.lib.ObjectId) Assisted(com.google.inject.assistedinject.Assisted) RevWalk(org.eclipse.jgit.revwalk.RevWalk) DiffUtil(com.google.gerrit.server.patch.DiffUtil) GitFileDiff(com.google.gerrit.server.patch.gitfilediff.GitFileDiff) DiffNotAvailableException(com.google.gerrit.server.patch.DiffNotAvailableException) List(java.util.List) Map(java.util.Map) Optional(java.util.Optional) FluentLogger(com.google.common.flogger.FluentLogger) GitFileDiffCacheKey(com.google.gerrit.server.patch.gitfilediff.GitFileDiffCacheKey) GitFileDiff(com.google.gerrit.server.patch.gitfilediff.GitFileDiff) ImmutableMap(com.google.common.collect.ImmutableMap)

Example 2 with DiffNotAvailableException

use of com.google.gerrit.server.patch.DiffNotAvailableException in project gerrit by GerritCodeReview.

the class ChangeEmail method getUnifiedDiff.

/**
 * Show patch set as unified difference.
 */
public String getUnifiedDiff() {
    Map<String, FileDiffOutput> modifiedFiles;
    try {
        modifiedFiles = listModifiedFiles();
        if (modifiedFiles.isEmpty()) {
            // Currently these always have a null oldId in the PatchList.
            return "[Octopus merge; cannot be formatted as a diff.]\n";
        }
    } catch (DiffNotAvailableException e) {
        logger.atSevere().withCause(e).log("Cannot format patch");
        return "";
    }
    int maxSize = args.settings.maximumDiffSize;
    TemporaryBuffer.Heap buf = new TemporaryBuffer.Heap(Math.min(HEAP_EST_SIZE, maxSize), maxSize);
    try (DiffFormatter fmt = new DiffFormatter(buf)) {
        try (Repository git = args.server.openRepository(change.getProject())) {
            try {
                ObjectId oldId = modifiedFiles.values().iterator().next().oldCommitId();
                ObjectId newId = modifiedFiles.values().iterator().next().newCommitId();
                if (oldId.equals(ObjectId.zeroId())) {
                    // DiffOperations returns ObjectId.zeroId if newCommit is a root commit, i.e. has no
                    // parents.
                    oldId = null;
                }
                fmt.setRepository(git);
                fmt.setDetectRenames(true);
                fmt.format(oldId, newId);
                return RawParseUtils.decode(buf.toByteArray());
            } catch (IOException e) {
                if (JGitText.get().inMemoryBufferLimitExceeded.equals(e.getMessage())) {
                    return "";
                }
                logger.atSevere().withCause(e).log("Cannot format patch");
                return "";
            }
        } catch (IOException e) {
            logger.atSevere().withCause(e).log("Cannot open repository to format patch");
            return "";
        }
    }
}
Also used : Repository(org.eclipse.jgit.lib.Repository) DiffNotAvailableException(com.google.gerrit.server.patch.DiffNotAvailableException) TemporaryBuffer(org.eclipse.jgit.util.TemporaryBuffer) ObjectId(org.eclipse.jgit.lib.ObjectId) IOException(java.io.IOException) DiffFormatter(org.eclipse.jgit.diff.DiffFormatter) FileDiffOutput(com.google.gerrit.server.patch.filediff.FileDiffOutput)

Example 3 with DiffNotAvailableException

use of com.google.gerrit.server.patch.DiffNotAvailableException in project gerrit by GerritCodeReview.

the class FileEditsPredicate method match.

@Override
public boolean match(ChangeData cd) {
    try {
        Map<String, FileDiffOutput> modifiedFiles = diffOperations.listModifiedFilesAgainstParent(cd.project(), cd.currentPatchSet().commitId(), /* parentNum= */
        0, DiffOptions.DEFAULTS);
        FileDiffOutput firstDiff = Iterables.getFirst(modifiedFiles.values(), /* defaultValue= */
        null);
        if (firstDiff == null) {
            // engine.fail();
            return false;
        }
        Pattern filePattern = null;
        Pattern editPattern = null;
        if (fileEditsArgs.filePattern().startsWith("^")) {
            // We validated the pattern before creating this predicate. No need to revalidate.
            String pattern = fileEditsArgs.filePattern();
            filePattern = Pattern.compile(pattern);
        }
        if (fileEditsArgs.editPattern().startsWith("^")) {
            // We validated the pattern before creating this predicate. No need to revalidate.
            String pattern = fileEditsArgs.editPattern();
            editPattern = Pattern.compile(pattern);
        }
        try (Repository repo = repoManager.openRepository(cd.project());
            ObjectReader reader = repo.newObjectReader();
            RevWalk rw = new RevWalk(reader)) {
            RevTree aTree = firstDiff.oldCommitId().equals(ObjectId.zeroId()) ? null : rw.parseTree(firstDiff.oldCommitId());
            RevTree bTree = rw.parseCommit(firstDiff.newCommitId()).getTree();
            for (FileDiffOutput entry : modifiedFiles.values()) {
                String newName = FilePathAdapter.getNewPath(entry.oldPath(), entry.newPath(), entry.changeType());
                String oldName = FilePathAdapter.getOldPath(entry.oldPath(), entry.changeType());
                if (Patch.isMagic(newName)) {
                    continue;
                }
                if (match(newName, fileEditsArgs.filePattern(), filePattern) || (oldName != null && match(oldName, fileEditsArgs.filePattern(), filePattern))) {
                    List<Edit> edits = entry.edits().stream().map(TaggedEdit::jgitEdit).collect(Collectors.toList());
                    if (edits.isEmpty()) {
                        continue;
                    }
                    Text tA;
                    if (oldName != null) {
                        tA = load(aTree, oldName, reader);
                    } else {
                        tA = load(aTree, newName, reader);
                    }
                    Text tB = load(bTree, newName, reader);
                    for (Edit edit : edits) {
                        if (tA != Text.EMPTY) {
                            String aDiff = tA.getString(edit.getBeginA(), edit.getEndA(), true);
                            if (match(aDiff, fileEditsArgs.editPattern(), editPattern)) {
                                return true;
                            }
                        }
                        if (tB != Text.EMPTY) {
                            String bDiff = tB.getString(edit.getBeginB(), edit.getEndB(), true);
                            if (match(bDiff, fileEditsArgs.editPattern(), editPattern)) {
                                return true;
                            }
                        }
                    }
                }
            }
        } catch (IOException e) {
            logger.atSevere().withCause(e).log("Error while evaluating commit edits.");
            return false;
        }
    } catch (DiffNotAvailableException e) {
        logger.atSevere().withCause(e).log("Diff error while evaluating commit edits.");
        return false;
    }
    return false;
}
Also used : Pattern(java.util.regex.Pattern) Edit(org.eclipse.jgit.diff.Edit) TaggedEdit(com.google.gerrit.server.patch.filediff.TaggedEdit) Text(com.google.gerrit.server.patch.Text) IOException(java.io.IOException) RevWalk(org.eclipse.jgit.revwalk.RevWalk) FileDiffOutput(com.google.gerrit.server.patch.filediff.FileDiffOutput) Repository(org.eclipse.jgit.lib.Repository) DiffNotAvailableException(com.google.gerrit.server.patch.DiffNotAvailableException) ObjectReader(org.eclipse.jgit.lib.ObjectReader) RevTree(org.eclipse.jgit.revwalk.RevTree)

Example 4 with DiffNotAvailableException

use of com.google.gerrit.server.patch.DiffNotAvailableException in project gerrit by GerritCodeReview.

the class EventFactory method asPatchSetAttribute.

/**
 * Create a PatchSetAttribute for the given patchset suitable for serialization to JSON.
 */
public PatchSetAttribute asPatchSetAttribute(RevWalk revWalk, Change change, PatchSet patchSet) {
    PatchSetAttribute p = new PatchSetAttribute();
    p.revision = patchSet.commitId().name();
    p.number = patchSet.number();
    p.ref = patchSet.refName();
    p.uploader = asAccountAttribute(patchSet.uploader());
    p.createdOn = patchSet.createdOn().getEpochSecond();
    PatchSet.Id pId = patchSet.id();
    try {
        p.parents = new ArrayList<>();
        RevCommit c = revWalk.parseCommit(ObjectId.fromString(p.revision));
        for (RevCommit parent : c.getParents()) {
            p.parents.add(parent.name());
        }
        UserIdentity author = emails.toUserIdentity(c.getAuthorIdent());
        if (author.getAccount() == null) {
            p.author = new AccountAttribute();
            p.author.email = author.getEmail();
            p.author.name = author.getName();
            p.author.username = "";
        } else {
            p.author = asAccountAttribute(author.getAccount());
        }
        Map<String, FileDiffOutput> modifiedFiles = diffOperations.listModifiedFilesAgainstParent(change.getProject(), patchSet.commitId(), /* parentNum= */
        0, DiffOptions.DEFAULTS);
        for (FileDiffOutput fileDiff : modifiedFiles.values()) {
            p.sizeDeletions += fileDiff.deletions();
            p.sizeInsertions += fileDiff.insertions();
        }
        p.kind = changeKindCache.getChangeKind(change, patchSet);
    } catch (IOException | StorageException e) {
        logger.atSevere().withCause(e).log("Cannot load patch set data for %s", patchSet.id());
    } catch (DiffNotAvailableException e) {
        logger.atSevere().withCause(e).log("Cannot get size information for %s.", pId);
    }
    return p;
}
Also used : AccountAttribute(com.google.gerrit.server.data.AccountAttribute) UserIdentity(com.google.gerrit.entities.UserIdentity) PatchSet(com.google.gerrit.entities.PatchSet) IOException(java.io.IOException) FileDiffOutput(com.google.gerrit.server.patch.filediff.FileDiffOutput) DiffNotAvailableException(com.google.gerrit.server.patch.DiffNotAvailableException) PatchSetAttribute(com.google.gerrit.server.data.PatchSetAttribute) StorageException(com.google.gerrit.exceptions.StorageException) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Example 5 with DiffNotAvailableException

use of com.google.gerrit.server.patch.DiffNotAvailableException in project gerrit by GerritCodeReview.

the class SubmitRequirementExpressionsValidator method onCommitReceived.

@Override
public List<CommitValidationMessage> onCommitReceived(CommitReceivedEvent event) throws CommitValidationException {
    try {
        if (!event.refName.equals(RefNames.REFS_CONFIG) || !isFileChanged(event, ProjectConfig.PROJECT_CONFIG)) {
            // validate the submit requirements in it
            return ImmutableList.of();
        }
        ProjectConfig projectConfig = getProjectConfig(event);
        ImmutableList<CommitValidationMessage> validationMessages = validateSubmitRequirementExpressions(projectConfig.getSubmitRequirementSections().values());
        if (!validationMessages.isEmpty()) {
            throw new CommitValidationException(String.format("invalid submit requirement expressions in %s (revision = %s)", ProjectConfig.PROJECT_CONFIG, projectConfig.getRevision()), validationMessages);
        }
        return ImmutableList.of();
    } catch (IOException | DiffNotAvailableException | ConfigInvalidException e) {
        throw new CommitValidationException(String.format("failed to validate submit requirement expressions in %s for revision %s in ref %s" + " of project %s", ProjectConfig.PROJECT_CONFIG, event.commit.getName(), RefNames.REFS_CONFIG, event.project.getNameKey()), e);
    }
}
Also used : DiffNotAvailableException(com.google.gerrit.server.patch.DiffNotAvailableException) ConfigInvalidException(org.eclipse.jgit.errors.ConfigInvalidException) CommitValidationException(com.google.gerrit.server.git.validators.CommitValidationException) IOException(java.io.IOException) CommitValidationMessage(com.google.gerrit.server.git.validators.CommitValidationMessage)

Aggregations

DiffNotAvailableException (com.google.gerrit.server.patch.DiffNotAvailableException)8 IOException (java.io.IOException)6 FileDiffOutput (com.google.gerrit.server.patch.filediff.FileDiffOutput)5 StorageException (com.google.gerrit.exceptions.StorageException)3 FluentLogger (com.google.common.flogger.FluentLogger)2 PatchSet (com.google.gerrit.entities.PatchSet)2 Inject (com.google.inject.Inject)2 Assisted (com.google.inject.assistedinject.Assisted)2 HashMap (java.util.HashMap)2 ObjectId (org.eclipse.jgit.lib.ObjectId)2 Repository (org.eclipse.jgit.lib.Repository)2 RevWalk (org.eclipse.jgit.revwalk.RevWalk)2 Strings (com.google.common.base.Strings)1 ImmutableMap (com.google.common.collect.ImmutableMap)1 FilenameComparator (com.google.gerrit.common.data.FilenameComparator)1 Account (com.google.gerrit.entities.Account)1 Change (com.google.gerrit.entities.Change)1 Comment (com.google.gerrit.entities.Comment)1 HumanComment (com.google.gerrit.entities.HumanComment)1 NotifyType (com.google.gerrit.entities.NotifyConfig.NotifyType)1