Search in sources :

Example 6 with CodeReviewCommit

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

the class MergeAlways method buildOps.

@Override
public List<SubmitStrategyOp> buildOps(Collection<CodeReviewCommit> toMerge) throws IntegrationException {
    List<CodeReviewCommit> sorted = args.mergeUtil.reduceToMinimalMerge(args.mergeSorter, toMerge);
    List<SubmitStrategyOp> ops = new ArrayList<>(sorted.size());
    if (args.mergeTip.getInitialTip() == null && !sorted.isEmpty()) {
        // The branch is unborn. Take a fast-forward resolution to
        // create the branch.
        CodeReviewCommit first = sorted.remove(0);
        ops.add(new FastForwardOp(args, first));
    }
    while (!sorted.isEmpty()) {
        CodeReviewCommit n = sorted.remove(0);
        ops.add(new MergeOneOp(args, n));
    }
    return ops;
}
Also used : ArrayList(java.util.ArrayList) CodeReviewCommit(com.google.gerrit.server.git.CodeReviewCommit)

Example 7 with CodeReviewCommit

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

the class MergeIfNecessary method buildOps.

@Override
public List<SubmitStrategyOp> buildOps(Collection<CodeReviewCommit> toMerge) throws IntegrationException {
    List<CodeReviewCommit> sorted = args.mergeUtil.reduceToMinimalMerge(args.mergeSorter, toMerge);
    List<SubmitStrategyOp> ops = new ArrayList<>(sorted.size());
    if (args.mergeTip.getInitialTip() == null || !args.submoduleOp.hasSubscription(args.destBranch)) {
        CodeReviewCommit firstFastForward = args.mergeUtil.getFirstFastForward(args.mergeTip.getInitialTip(), args.rw, sorted);
        if (firstFastForward != null && !firstFastForward.equals(args.mergeTip.getInitialTip())) {
            ops.add(new FastForwardOp(args, firstFastForward));
        }
    }
    // For every other commit do a pair-wise merge.
    while (!sorted.isEmpty()) {
        CodeReviewCommit n = sorted.remove(0);
        ops.add(new MergeOneOp(args, n));
    }
    return ops;
}
Also used : ArrayList(java.util.ArrayList) CodeReviewCommit(com.google.gerrit.server.git.CodeReviewCommit)

Example 8 with CodeReviewCommit

use of com.google.gerrit.server.git.CodeReviewCommit 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 9 with CodeReviewCommit

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

the class SubmitStrategyOp method updateRepo.

@Override
public final void updateRepo(RepoContext ctx) throws Exception {
    logDebug("{}#updateRepo for change {}", getClass().getSimpleName(), toMerge.change().getId());
    checkState(ctx.getRevWalk() == args.rw, "SubmitStrategyOp requires callers to call BatchUpdate#setRepository with exactly the same" + " CodeReviewRevWalk instance from the SubmitStrategy.Arguments: %s != %s", ctx.getRevWalk(), args.rw);
    // Run the submit strategy implementation and record the merge tip state so
    // we can create the ref update.
    CodeReviewCommit tipBefore = args.mergeTip.getCurrentTip();
    alreadyMerged = getAlreadyMergedCommit(ctx);
    if (alreadyMerged == null) {
        updateRepoImpl(ctx);
    } else {
        logDebug("Already merged as {}", alreadyMerged.name());
    }
    CodeReviewCommit tipAfter = args.mergeTip.getCurrentTip();
    if (Objects.equals(tipBefore, tipAfter)) {
        logDebug("Did not move tip", getClass().getSimpleName());
        return;
    } else if (tipAfter == null) {
        logDebug("No merge tip, no update to perform");
        return;
    }
    logDebug("Moved tip from {} to {}", tipBefore, tipAfter);
    checkProjectConfig(ctx, tipAfter);
    // Needed by postUpdate, at which point mergeTip will have advanced further,
    // so it's easier to just snapshot the command.
    command = new ReceiveCommand(firstNonNull(tipBefore, ObjectId.zeroId()), tipAfter, getDest().get());
    ctx.addRefUpdate(command);
    args.submoduleOp.addBranchTip(getDest(), tipAfter);
}
Also used : ReceiveCommand(org.eclipse.jgit.transport.ReceiveCommand) CodeReviewCommit(com.google.gerrit.server.git.CodeReviewCommit)

Example 10 with CodeReviewCommit

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

the class RebaseSubmitStrategy method buildOps.

@Override
public List<SubmitStrategyOp> buildOps(Collection<CodeReviewCommit> toMerge) throws IntegrationException {
    List<CodeReviewCommit> sorted;
    try {
        sorted = args.rebaseSorter.sort(toMerge);
    } catch (IOException e) {
        throw new IntegrationException("Commit sorting failed", e);
    }
    List<SubmitStrategyOp> ops = new ArrayList<>(sorted.size());
    boolean first = true;
    for (CodeReviewCommit c : sorted) {
        if (c.getParentCount() > 1) {
            // Since there is a merge commit, sort and prune again using
            // MERGE_IF_NECESSARY semantics to avoid creating duplicate
            // commits.
            //
            sorted = args.mergeUtil.reduceToMinimalMerge(args.mergeSorter, sorted);
            break;
        }
    }
    while (!sorted.isEmpty()) {
        CodeReviewCommit n = sorted.remove(0);
        if (first && args.mergeTip.getInitialTip() == null) {
            // TODO(tandrii): Cherry-Pick strategy does this too, but it's wrong
            // and can be fixed.
            ops.add(new FastForwardOp(args, n));
        } else if (n.getParentCount() == 0) {
            ops.add(new RebaseRootOp(n));
        } else if (n.getParentCount() == 1) {
            ops.add(new RebaseOneOp(n));
        } else {
            ops.add(new RebaseMultipleParentsOp(n));
        }
        first = false;
    }
    return ops;
}
Also used : IntegrationException(com.google.gerrit.server.git.IntegrationException) ArrayList(java.util.ArrayList) IOException(java.io.IOException) CodeReviewCommit(com.google.gerrit.server.git.CodeReviewCommit)

Aggregations

CodeReviewCommit (com.google.gerrit.server.git.CodeReviewCommit)13 ArrayList (java.util.ArrayList)8 Change (com.google.gerrit.reviewdb.client.Change)4 IntegrationException (com.google.gerrit.server.git.IntegrationException)4 Branch (com.google.gerrit.reviewdb.client.Branch)2 PatchSet (com.google.gerrit.reviewdb.client.PatchSet)2 IdentifiedUser (com.google.gerrit.server.IdentifiedUser)2 CodeReviewRevWalk (com.google.gerrit.server.git.CodeReviewCommit.CodeReviewRevWalk)2 ProjectState (com.google.gerrit.server.project.ProjectState)2 OrmException (com.google.gwtorm.server.OrmException)2 ObjectId (org.eclipse.jgit.lib.ObjectId)2 Repository (org.eclipse.jgit.lib.Repository)2 Function (com.google.common.base.Function)1 MoreObjects.firstNonNull (com.google.common.base.MoreObjects.firstNonNull)1 Preconditions.checkNotNull (com.google.common.base.Preconditions.checkNotNull)1 Preconditions.checkState (com.google.common.base.Preconditions.checkState)1 Iterables (com.google.common.collect.Iterables)1 SubmitRecord (com.google.gerrit.common.data.SubmitRecord)1 MergeConflictException (com.google.gerrit.extensions.restapi.MergeConflictException)1 Account (com.google.gerrit.reviewdb.client.Account)1