
com.google.gerrit.server.git.strategy.SubmitStrategy Maven / Gradle / Ivy
// Copyright (C) 2012 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.server.git.strategy;
import com.google.gerrit.extensions.common.SubmitType;
import com.google.gerrit.reviewdb.client.Branch;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSetApproval;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ApprovalsUtil;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.git.CodeReviewCommit;
import com.google.gerrit.server.git.MergeException;
import com.google.gerrit.server.git.MergeSorter;
import com.google.gerrit.server.git.MergeUtil;
import com.google.gerrit.server.index.ChangeIndexer;
import com.google.gerrit.server.project.ChangeControl;
import com.google.inject.Provider;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.RefUpdate.Result;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevFlag;
import org.eclipse.jgit.revwalk.RevWalk;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Base class that submit strategies must extend. A submit strategy for a
* certain {@link SubmitType} defines how the submitted commits should be
* merged.
*/
public abstract class SubmitStrategy {
private PersonIdent refLogIdent;
static class Arguments {
protected final IdentifiedUser.GenericFactory identifiedUserFactory;
protected final Provider serverIdent;
protected final ReviewDb db;
protected final ChangeControl.GenericFactory changeControlFactory;
protected final Repository repo;
protected final RevWalk rw;
protected final ObjectInserter inserter;
protected final RevFlag canMergeFlag;
protected final Set alreadyAccepted;
protected final Branch.NameKey destBranch;
protected final ApprovalsUtil approvalsUtil;
protected final MergeUtil mergeUtil;
protected final ChangeIndexer indexer;
protected final MergeSorter mergeSorter;
Arguments(final IdentifiedUser.GenericFactory identifiedUserFactory,
final Provider serverIdent, final ReviewDb db,
final ChangeControl.GenericFactory changeControlFactory,
final Repository repo, final RevWalk rw, final ObjectInserter inserter,
final RevFlag canMergeFlag, final Set alreadyAccepted,
final Branch.NameKey destBranch, final ApprovalsUtil approvalsUtil,
final MergeUtil mergeUtil, final ChangeIndexer indexer) {
this.identifiedUserFactory = identifiedUserFactory;
this.serverIdent = serverIdent;
this.db = db;
this.changeControlFactory = changeControlFactory;
this.repo = repo;
this.rw = rw;
this.inserter = inserter;
this.canMergeFlag = canMergeFlag;
this.alreadyAccepted = alreadyAccepted;
this.destBranch = destBranch;
this.approvalsUtil = approvalsUtil;
this.mergeUtil = mergeUtil;
this.indexer = indexer;
this.mergeSorter = new MergeSorter(rw, alreadyAccepted, canMergeFlag);
}
}
protected final Arguments args;
SubmitStrategy(final Arguments args) {
this.args = args;
}
/**
* Runs this submit strategy. If possible the provided commits will be merged
* with this submit strategy.
*
* @param mergeTip the mergeTip
* @param toMerge the list of submitted commits that should be merged using
* this submit strategy
* @return the new mergeTip
* @throws MergeException
*/
public final CodeReviewCommit run(final CodeReviewCommit mergeTip,
final List toMerge) throws MergeException {
refLogIdent = null;
return _run(mergeTip, toMerge);
}
/**
* Runs this submit strategy. If possible the provided commits will be merged
* with this submit strategy.
*
* @param mergeTip the mergeTip
* @param toMerge the list of submitted commits that should be merged using
* this submit strategy
* @return the new mergeTip
* @throws MergeException
*/
protected abstract CodeReviewCommit _run(CodeReviewCommit mergeTip,
List toMerge) throws MergeException;
/**
* Checks whether the given commit can be merged.
*
* Subclasses must ensure that invoking this method does neither modify the
* git repository nor the Gerrit database.
*
* @param mergeTip the mergeTip
* @param toMerge the commit for which it should be checked whether it can be
* merged or not
* @return {@code true} if the given commit can be merged, otherwise
* {@code false}
* @throws MergeException
*/
public abstract boolean dryRun(CodeReviewCommit mergeTip,
CodeReviewCommit toMerge) throws MergeException;
/**
* Returns the PersonIdent that should be used for the ref log entries when
* updating the destination branch. The ref log identity may be set after the
* {@link #run(CodeReviewCommit, List)} method finished.
*
* Do only call this method after the {@link #run(CodeReviewCommit, List)}
* method has been invoked.
*
* @return the ref log identity, may be {@code null}
*/
public final PersonIdent getRefLogIdent() {
return refLogIdent;
}
/**
* Returns all commits that have been newly created for the changes that are
* getting merged.
*
* By default this method is returning an empty map, but subclasses may
* overwrite this method to provide newly created commits.
*
* Do only call this method after the {@link #run(CodeReviewCommit, List)}
* method has been invoked.
*
* @return new commits created for changes that are getting merged
*/
public Map getNewCommits() {
return Collections.emptyMap();
}
/**
* Returns whether a merge that failed with
* {@link Result#LOCK_FAILURE} should be retried.
*
* May be overwritten by subclasses.
*
* @return {@code true} if a merge that failed with
* {@link Result#LOCK_FAILURE} should be retried, otherwise
* {@code false}
*/
public boolean retryOnLockFailure() {
return true;
}
/**
* Sets the ref log identity if it wasn't set yet.
*
* @param submitApproval the approval that submitted the patch set
*/
protected final void setRefLogIdent(final PatchSetApproval submitApproval) {
if (refLogIdent == null && submitApproval != null) {
refLogIdent =
args.identifiedUserFactory.create(submitApproval.getAccountId())
.newRefLogIdent();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy