Search in sources :

Example 1 with IntegrationException

use of com.google.gerrit.server.git.IntegrationException in project gerrit by GerritCodeReview.

the class SubmitDryRun method run.

public boolean run(SubmitType submitType, Repository repo, CodeReviewRevWalk rw, Branch.NameKey destBranch, ObjectId tip, ObjectId toMerge, Set<RevCommit> alreadyAccepted) throws IntegrationException, NoSuchProjectException, IOException {
    CodeReviewCommit tipCommit = rw.parseCommit(tip);
    CodeReviewCommit toMergeCommit = rw.parseCommit(toMerge);
    RevFlag canMerge = rw.newFlag("CAN_MERGE");
    toMergeCommit.add(canMerge);
    Arguments args = new Arguments(repo, rw, mergeUtilFactory.create(getProject(destBranch)), new MergeSorter(rw, alreadyAccepted, canMerge, ImmutableSet.of(toMergeCommit)));
    switch(submitType) {
        case CHERRY_PICK:
            return CherryPick.dryRun(args, tipCommit, toMergeCommit);
        case FAST_FORWARD_ONLY:
            return FastForwardOnly.dryRun(args, tipCommit, toMergeCommit);
        case MERGE_ALWAYS:
            return MergeAlways.dryRun(args, tipCommit, toMergeCommit);
        case MERGE_IF_NECESSARY:
            return MergeIfNecessary.dryRun(args, tipCommit, toMergeCommit);
        case REBASE_IF_NECESSARY:
            return RebaseIfNecessary.dryRun(args, repo, tipCommit, toMergeCommit);
        case REBASE_ALWAYS:
            return RebaseAlways.dryRun(args, repo, tipCommit, toMergeCommit);
        default:
            String errorMsg = "No submit strategy for: " + submitType;
            log.error(errorMsg);
            throw new IntegrationException(errorMsg);
    }
}
Also used : IntegrationException(com.google.gerrit.server.git.IntegrationException) RevFlag(org.eclipse.jgit.revwalk.RevFlag) MergeSorter(com.google.gerrit.server.git.MergeSorter) CodeReviewCommit(com.google.gerrit.server.git.CodeReviewCommit)

Example 2 with IntegrationException

use of com.google.gerrit.server.git.IntegrationException in project gerrit by GerritCodeReview.

the class ConflictsPredicate method predicates.

public static List<Predicate<ChangeData>> predicates(final Arguments args, String value, List<Change> changes) throws QueryParseException, OrmException {
    int indexTerms = 0;
    List<Predicate<ChangeData>> changePredicates = Lists.newArrayListWithCapacity(changes.size());
    final Provider<ReviewDb> db = args.db;
    for (final Change c : changes) {
        final ChangeDataCache changeDataCache = new ChangeDataCache(c, db, args.changeDataFactory, args.projectCache);
        List<String> files = listFiles(c, args, changeDataCache);
        indexTerms += 3 + files.size();
        if (indexTerms > args.indexConfig.maxTerms()) {
            // later on in the query parsing.
            throw new QueryParseException(TOO_MANY_FILES);
        }
        List<Predicate<ChangeData>> filePredicates = Lists.newArrayListWithCapacity(files.size());
        for (String file : files) {
            filePredicates.add(new EqualsPathPredicate(ChangeQueryBuilder.FIELD_PATH, file));
        }
        List<Predicate<ChangeData>> predicatesForOneChange = Lists.newArrayListWithCapacity(5);
        predicatesForOneChange.add(not(new LegacyChangeIdPredicate(c.getId())));
        predicatesForOneChange.add(new ProjectPredicate(c.getProject().get()));
        predicatesForOneChange.add(new RefPredicate(c.getDest().get()));
        predicatesForOneChange.add(or(or(filePredicates), new IsMergePredicate(args, value)));
        predicatesForOneChange.add(new ChangeOperatorPredicate(ChangeQueryBuilder.FIELD_CONFLICTS, value) {

            @Override
            public boolean match(ChangeData object) throws OrmException {
                Change otherChange = object.change();
                if (otherChange == null) {
                    return false;
                }
                if (!otherChange.getDest().equals(c.getDest())) {
                    return false;
                }
                SubmitTypeRecord str = object.submitTypeRecord();
                if (!str.isOk()) {
                    return false;
                }
                ObjectId other = ObjectId.fromString(object.currentPatchSet().getRevision().get());
                ConflictKey conflictsKey = new ConflictKey(changeDataCache.getTestAgainst(), other, str.type, changeDataCache.getProjectState().isUseContentMerge());
                Boolean conflicts = args.conflictsCache.getIfPresent(conflictsKey);
                if (conflicts != null) {
                    return conflicts;
                }
                try (Repository repo = args.repoManager.openRepository(otherChange.getProject());
                    CodeReviewRevWalk rw = CodeReviewCommit.newRevWalk(repo)) {
                    conflicts = !args.submitDryRun.run(str.type, repo, rw, otherChange.getDest(), changeDataCache.getTestAgainst(), other, getAlreadyAccepted(repo, rw));
                    args.conflictsCache.put(conflictsKey, conflicts);
                    return conflicts;
                } catch (IntegrationException | NoSuchProjectException | IOException e) {
                    throw new OrmException(e);
                }
            }

            @Override
            public int getCost() {
                return 5;
            }

            private Set<RevCommit> getAlreadyAccepted(Repository repo, RevWalk rw) throws IntegrationException {
                try {
                    Set<RevCommit> accepted = new HashSet<>();
                    SubmitDryRun.addCommits(changeDataCache.getAlreadyAccepted(repo), rw, accepted);
                    ObjectId tip = changeDataCache.getTestAgainst();
                    if (tip != null) {
                        accepted.add(rw.parseCommit(tip));
                    }
                    return accepted;
                } catch (OrmException | IOException e) {
                    throw new IntegrationException("Failed to determine already accepted commits.", e);
                }
            }
        });
        changePredicates.add(and(predicatesForOneChange));
    }
    return changePredicates;
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) OrPredicate(com.google.gerrit.server.query.OrPredicate) Predicate(com.google.gerrit.server.query.Predicate) OrmException(com.google.gwtorm.server.OrmException) ReviewDb(com.google.gerrit.reviewdb.server.ReviewDb) IntegrationException(com.google.gerrit.server.git.IntegrationException) ObjectId(org.eclipse.jgit.lib.ObjectId) CodeReviewRevWalk(com.google.gerrit.server.git.CodeReviewCommit.CodeReviewRevWalk) Change(com.google.gerrit.reviewdb.client.Change) CodeReviewRevWalk(com.google.gerrit.server.git.CodeReviewCommit.CodeReviewRevWalk) RevWalk(org.eclipse.jgit.revwalk.RevWalk) QueryParseException(com.google.gerrit.server.query.QueryParseException) Repository(org.eclipse.jgit.lib.Repository) SubmitTypeRecord(com.google.gerrit.common.data.SubmitTypeRecord)

Example 3 with IntegrationException

use of com.google.gerrit.server.git.IntegrationException in project gerrit by GerritCodeReview.

the class CherryPickChange method cherryPick.

public Change.Id cherryPick(BatchUpdate.Factory batchUpdateFactory, @Nullable Change.Id sourceChangeId, @Nullable PatchSet.Id sourcePatchId, @Nullable Branch.NameKey sourceBranch, @Nullable String sourceChangeTopic, Project.NameKey project, ObjectId sourceCommit, CherryPickInput input, String targetRef, RefControl targetRefControl) throws OrmException, IOException, InvalidChangeOperationException, IntegrationException, UpdateException, RestApiException {
    if (Strings.isNullOrEmpty(targetRef)) {
        throw new InvalidChangeOperationException("Cherry Pick: Destination branch cannot be null or empty");
    }
    String destinationBranch = RefNames.shortName(targetRef);
    IdentifiedUser identifiedUser = user.get();
    try (Repository git = gitManager.openRepository(project);
        // before patch sets are updated.
        ObjectInserter oi = git.newObjectInserter();
        ObjectReader reader = oi.newReader();
        CodeReviewRevWalk revWalk = CodeReviewCommit.newRevWalk(reader)) {
        Ref destRef = git.getRefDatabase().exactRef(targetRef);
        if (destRef == null) {
            throw new InvalidChangeOperationException(String.format("Branch %s does not exist.", destinationBranch));
        }
        CodeReviewCommit mergeTip = revWalk.parseCommit(destRef.getObjectId());
        CodeReviewCommit commitToCherryPick = revWalk.parseCommit(sourceCommit);
        if (input.parent <= 0 || input.parent > commitToCherryPick.getParentCount()) {
            throw new InvalidChangeOperationException(String.format("Cherry Pick: Parent %s does not exist. Please specify a parent in" + " range [1, %s].", input.parent, commitToCherryPick.getParentCount()));
        }
        Timestamp now = TimeUtil.nowTs();
        PersonIdent committerIdent = identifiedUser.newCommitterIdent(now, serverTimeZone);
        final ObjectId computedChangeId = ChangeIdUtil.computeChangeId(commitToCherryPick.getTree(), mergeTip, commitToCherryPick.getAuthorIdent(), committerIdent, input.message);
        String commitMessage = ChangeIdUtil.insertId(input.message, computedChangeId).trim() + '\n';
        CodeReviewCommit cherryPickCommit;
        try {
            ProjectState projectState = targetRefControl.getProjectControl().getProjectState();
            cherryPickCommit = mergeUtilFactory.create(projectState).createCherryPickFromCommit(oi, git.getConfig(), mergeTip, commitToCherryPick, committerIdent, commitMessage, revWalk, input.parent - 1, false);
            Change.Key changeKey;
            final List<String> idList = cherryPickCommit.getFooterLines(FooterConstants.CHANGE_ID);
            if (!idList.isEmpty()) {
                final String idStr = idList.get(idList.size() - 1).trim();
                changeKey = new Change.Key(idStr);
            } else {
                changeKey = new Change.Key("I" + computedChangeId.name());
            }
            Branch.NameKey newDest = new Branch.NameKey(project, destRef.getName());
            List<ChangeData> destChanges = queryProvider.get().setLimit(2).byBranchKey(newDest, changeKey);
            if (destChanges.size() > 1) {
                throw new InvalidChangeOperationException("Several changes with key " + changeKey + " reside on the same branch. " + "Cannot create a new patch set.");
            }
            try (BatchUpdate bu = batchUpdateFactory.create(db.get(), project, identifiedUser, now)) {
                bu.setRepository(git, revWalk, oi);
                Change.Id result;
                if (destChanges.size() == 1) {
                    // The change key exists on the destination branch. The cherry pick
                    // will be added as a new patch set.
                    ChangeControl destCtl = targetRefControl.getProjectControl().controlFor(destChanges.get(0).notes());
                    result = insertPatchSet(bu, git, destCtl, cherryPickCommit, input);
                } else {
                    // Change key not found on destination branch. We can create a new
                    // change.
                    String newTopic = null;
                    if (!Strings.isNullOrEmpty(sourceChangeTopic)) {
                        newTopic = sourceChangeTopic + "-" + newDest.getShortName();
                    }
                    result = createNewChange(bu, cherryPickCommit, targetRefControl.getRefName(), newTopic, sourceBranch, sourceCommit, input);
                    if (sourceChangeId != null && sourcePatchId != null) {
                        bu.addOp(sourceChangeId, new AddMessageToSourceChangeOp(changeMessagesUtil, sourcePatchId, destinationBranch, cherryPickCommit));
                    }
                }
                bu.execute();
                return result;
            }
        } catch (MergeIdenticalTreeException | MergeConflictException e) {
            throw new IntegrationException("Cherry pick failed: " + e.getMessage());
        }
    }
}
Also used : InvalidChangeOperationException(com.google.gerrit.server.project.InvalidChangeOperationException) Timestamp(java.sql.Timestamp) BatchUpdate(com.google.gerrit.server.update.BatchUpdate) MergeConflictException(com.google.gerrit.extensions.restapi.MergeConflictException) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) Branch(com.google.gerrit.reviewdb.client.Branch) ChangeControl(com.google.gerrit.server.project.ChangeControl) ObjectReader(org.eclipse.jgit.lib.ObjectReader) IntegrationException(com.google.gerrit.server.git.IntegrationException) ObjectId(org.eclipse.jgit.lib.ObjectId) CodeReviewRevWalk(com.google.gerrit.server.git.CodeReviewCommit.CodeReviewRevWalk) Change(com.google.gerrit.reviewdb.client.Change) IdentifiedUser(com.google.gerrit.server.IdentifiedUser) CodeReviewCommit(com.google.gerrit.server.git.CodeReviewCommit) ChangeData(com.google.gerrit.server.query.change.ChangeData) MergeIdenticalTreeException(com.google.gerrit.server.git.MergeIdenticalTreeException) Repository(org.eclipse.jgit.lib.Repository) Ref(org.eclipse.jgit.lib.Ref) PersonIdent(org.eclipse.jgit.lib.PersonIdent) GerritPersonIdent(com.google.gerrit.server.GerritPersonIdent) ProjectState(com.google.gerrit.server.project.ProjectState)

Example 4 with IntegrationException

use of com.google.gerrit.server.git.IntegrationException in project gerrit by GerritCodeReview.

the class CherryPickCommit method applyImpl.

@Override
public ChangeInfo applyImpl(BatchUpdate.Factory updateFactory, CommitResource rsrc, CherryPickInput input) throws OrmException, IOException, UpdateException, RestApiException {
    RevCommit commit = rsrc.getCommit();
    String message = Strings.nullToEmpty(input.message).trim();
    input.message = message.isEmpty() ? commit.getFullMessage() : message;
    String destination = Strings.nullToEmpty(input.destination).trim();
    input.parent = input.parent == null ? 1 : input.parent;
    if (destination.isEmpty()) {
        throw new BadRequestException("destination must be non-empty");
    }
    ProjectControl projectControl = rsrc.getProject();
    Capable capable = projectControl.canPushToAtLeastOneRef();
    if (capable != Capable.OK) {
        throw new AuthException(capable.getMessage());
    }
    String refName = RefNames.fullName(destination);
    RefControl refControl = projectControl.controlForRef(refName);
    if (!refControl.canUpload()) {
        throw new AuthException("Not allowed to cherry pick " + commit + " to " + destination);
    }
    Project.NameKey project = projectControl.getProject().getNameKey();
    try {
        Change.Id cherryPickedChangeId = cherryPickChange.cherryPick(updateFactory, null, null, null, null, project, commit, input, refName, refControl);
        return json.noOptions().format(project, cherryPickedChangeId);
    } catch (InvalidChangeOperationException e) {
        throw new BadRequestException(e.getMessage());
    } catch (IntegrationException e) {
        throw new ResourceConflictException(e.getMessage());
    }
}
Also used : InvalidChangeOperationException(com.google.gerrit.server.project.InvalidChangeOperationException) IntegrationException(com.google.gerrit.server.git.IntegrationException) RefControl(com.google.gerrit.server.project.RefControl) AuthException(com.google.gerrit.extensions.restapi.AuthException) Change(com.google.gerrit.reviewdb.client.Change) ProjectControl(com.google.gerrit.server.project.ProjectControl) Project(com.google.gerrit.reviewdb.client.Project) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) Capable(com.google.gerrit.common.data.Capable) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Example 5 with IntegrationException

use of com.google.gerrit.server.git.IntegrationException in project gerrit by GerritCodeReview.

the class CherryPick method applyImpl.

@Override
protected ChangeInfo applyImpl(BatchUpdate.Factory updateFactory, RevisionResource revision, CherryPickInput input) throws OrmException, IOException, UpdateException, RestApiException {
    final ChangeControl control = revision.getControl();
    input.parent = input.parent == null ? 1 : input.parent;
    if (input.message == null || input.message.trim().isEmpty()) {
        throw new BadRequestException("message must be non-empty");
    } else if (input.destination == null || input.destination.trim().isEmpty()) {
        throw new BadRequestException("destination must be non-empty");
    }
    if (!control.isVisible(dbProvider.get())) {
        throw new AuthException("Cherry pick not permitted");
    }
    ProjectControl projectControl = control.getProjectControl();
    Capable capable = projectControl.canPushToAtLeastOneRef();
    if (capable != Capable.OK) {
        throw new AuthException(capable.getMessage());
    }
    String refName = RefNames.fullName(input.destination);
    RefControl refControl = projectControl.controlForRef(refName);
    if (!refControl.canUpload()) {
        throw new AuthException("Not allowed to cherry pick " + revision.getChange().getId().toString() + " to " + input.destination);
    }
    try {
        Change.Id cherryPickedChangeId = cherryPickChange.cherryPick(updateFactory, revision.getChange(), revision.getPatchSet(), input, refName, refControl);
        return json.noOptions().format(revision.getProject(), cherryPickedChangeId);
    } catch (InvalidChangeOperationException e) {
        throw new BadRequestException(e.getMessage());
    } catch (IntegrationException | NoSuchChangeException e) {
        throw new ResourceConflictException(e.getMessage());
    }
}
Also used : InvalidChangeOperationException(com.google.gerrit.server.project.InvalidChangeOperationException) IntegrationException(com.google.gerrit.server.git.IntegrationException) RefControl(com.google.gerrit.server.project.RefControl) AuthException(com.google.gerrit.extensions.restapi.AuthException) Change(com.google.gerrit.reviewdb.client.Change) ProjectControl(com.google.gerrit.server.project.ProjectControl) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) Capable(com.google.gerrit.common.data.Capable) NoSuchChangeException(com.google.gerrit.server.project.NoSuchChangeException) ChangeControl(com.google.gerrit.server.project.ChangeControl) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException)

Aggregations

IntegrationException (com.google.gerrit.server.git.IntegrationException)8 Change (com.google.gerrit.reviewdb.client.Change)4 ResourceConflictException (com.google.gerrit.extensions.restapi.ResourceConflictException)3 CodeReviewCommit (com.google.gerrit.server.git.CodeReviewCommit)3 InvalidChangeOperationException (com.google.gerrit.server.project.InvalidChangeOperationException)3 Capable (com.google.gerrit.common.data.Capable)2 AuthException (com.google.gerrit.extensions.restapi.AuthException)2 BadRequestException (com.google.gerrit.extensions.restapi.BadRequestException)2 CodeReviewRevWalk (com.google.gerrit.server.git.CodeReviewCommit.CodeReviewRevWalk)2 ChangeControl (com.google.gerrit.server.project.ChangeControl)2 ProjectControl (com.google.gerrit.server.project.ProjectControl)2 RefControl (com.google.gerrit.server.project.RefControl)2 OrmException (com.google.gwtorm.server.OrmException)2 IOException (java.io.IOException)2 ObjectId (org.eclipse.jgit.lib.ObjectId)2 Repository (org.eclipse.jgit.lib.Repository)2 SubmitTypeRecord (com.google.gerrit.common.data.SubmitTypeRecord)1 MergeConflictException (com.google.gerrit.extensions.restapi.MergeConflictException)1 Branch (com.google.gerrit.reviewdb.client.Branch)1 Project (com.google.gerrit.reviewdb.client.Project)1