Convert MergeOp to use BatchRefUpdate

Since we now do not flush the ObjectInserter until the submit strategy
has been run on all pending changes, it is not safe to update patch
set refs to point to new cherry-pick commits until the end of the loop
as well.

This produces a different failure case from what we had previously:
instead of potentially having refs with no pointers from the database,
the situation is reversed. If a ref update fails, there may still be
PatchSets in the database pointing to nonexistent refs.

Change-Id: I0594aef6f765a7beee586516fffeb71f040bdc46
This commit is contained in:
Dave Borowitz
2015-01-23 15:47:29 -08:00
parent b67addf513
commit c20148c8e2
11 changed files with 134 additions and 95 deletions

View File

@@ -64,6 +64,7 @@ import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.diff.DiffFormatter;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
@@ -254,6 +255,16 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
ChangeInfo c = getChange(changeId, CURRENT_REVISION);
assertThat(c.currentRevision).isEqualTo(expectedId.name());
assertThat(c.revisions.get(expectedId.name())._number).isEqualTo(expectedNum);
Repository repo =
repoManager.openRepository(new Project.NameKey(c.project));
try {
Ref ref = repo.getRef(
new PatchSet.Id(new Change.Id(c._number), expectedNum).toRefName());
assertThat(ref).isNotNull();
assertThat(ref.getObjectId()).isEqualTo(expectedId);
} finally {
repo.close();
}
}
protected void assertApproved(String changeId) throws IOException {

View File

@@ -241,6 +241,7 @@ public class MergeabilityCacheImpl implements MergeabilityCache {
rw,
null /*inserter*/,
canMerge,
null /*batchRefUpdate*/,
accepted,
key.load.dest).dryRun(tip, rev);
} finally {

View File

@@ -52,6 +52,7 @@ import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import org.eclipse.jgit.lib.BatchRefUpdate;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.Repository;
@@ -110,6 +111,7 @@ public class PatchSetInserter {
private boolean runHooks;
private boolean sendMail;
private Account.Id uploader;
private BatchRefUpdate batchRefUpdate;
@Inject
public PatchSetInserter(ChangeHooks hooks,
@@ -214,6 +216,11 @@ public class PatchSetInserter {
return this;
}
public PatchSetInserter setBatchRefUpdate(BatchRefUpdate batchRefUpdate) {
this.batchRefUpdate = batchRefUpdate;
return this;
}
public Change insert() throws InvalidChangeOperationException, OrmException,
IOException, NoSuchChangeException {
init();
@@ -221,16 +228,23 @@ public class PatchSetInserter {
Change c = ctl.getChange();
Change updatedChange;
RefUpdate ru = git.updateRef(patchSet.getRefName());
ru.setExpectedOldObjectId(ObjectId.zeroId());
ru.setNewObjectId(commit);
ru.disableRefLog();
if (ru.update(revWalk) != RefUpdate.Result.NEW) {
throw new IOException(String.format(
"Failed to create ref %s in %s: %s", patchSet.getRefName(),
c.getDest().getParentKey().get(), ru.getResult()));
if (batchRefUpdate != null) {
// Caller passed in update; add command, but don't execute.
batchRefUpdate.addCommand(new ReceiveCommand(ObjectId.zeroId(), commit,
patchSet.getRefName(), ReceiveCommand.Type.CREATE));
} else {
RefUpdate ru = git.updateRef(patchSet.getRefName());
ru.setExpectedOldObjectId(ObjectId.zeroId());
ru.setNewObjectId(commit);
ru.disableRefLog();
if (ru.update(revWalk) != RefUpdate.Result.NEW) {
throw new IOException(String.format(
"Failed to create ref %s in %s: %s", patchSet.getRefName(),
c.getDest().getParentKey().get(), ru.getResult()));
}
gitRefUpdated.fire(c.getProject(), ru);
}
gitRefUpdated.fire(c.getProject(), ru);
final PatchSet.Id currentPatchSetId = c.currentPatchSetId();

View File

@@ -14,6 +14,7 @@
package com.google.gerrit.server.changedetail;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.TimeUtil;
import com.google.gerrit.common.errors.EmailException;
import com.google.gerrit.reviewdb.client.Branch;
@@ -42,6 +43,7 @@ import com.google.inject.Provider;
import com.google.inject.Singleton;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.BatchRefUpdate;
import org.eclipse.jgit.lib.CommitBuilder;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
@@ -138,7 +140,7 @@ public class RebaseChange {
rebase(git, rw, inserter, patchSetId, change,
uploader, baseCommit, mergeUtilFactory.create(
changeControl.getProjectControl().getProjectState(), true),
committerIdent, true, true, ValidatePolicy.GERRIT);
committerIdent, true, true, ValidatePolicy.GERRIT, null);
} catch (MergeConflictException e) {
throw new IOException(e.getMessage());
} finally {
@@ -268,6 +270,8 @@ public class RebaseChange {
* @param sendMail if a mail notification should be sent for the new patch set
* @param runHooks if hooks should be run for the new patch set
* @param validate if commit validation should be run for the new patch set
* @param batchRefUpdate if not null, a batch ref update for creating new
* refs, which will not be executed.
* @return the new patch set which is based on the given base commit
* @throws NoSuchChangeException thrown if the change to which the patch set
* belongs does not exist or is not visible to the user
@@ -275,14 +279,13 @@ public class RebaseChange {
* @throws IOException thrown if rebase is not possible or not needed
* @throws InvalidChangeOperationException thrown if rebase is not allowed
*/
public PatchSet rebase(final Repository git, final RevWalk revWalk,
final ObjectInserter inserter, final PatchSet.Id patchSetId,
final Change change, final IdentifiedUser uploader, final RevCommit baseCommit,
final MergeUtil mergeUtil, PersonIdent committerIdent,
boolean sendMail, boolean runHooks, ValidatePolicy validate)
throws NoSuchChangeException,
OrmException, IOException, InvalidChangeOperationException,
MergeConflictException {
public PatchSet rebase(Repository git, RevWalk revWalk,
ObjectInserter inserter, PatchSet.Id patchSetId, Change change,
IdentifiedUser uploader, RevCommit baseCommit, MergeUtil mergeUtil,
PersonIdent committerIdent, boolean sendMail, boolean runHooks,
ValidatePolicy validate, @Nullable BatchRefUpdate batchRefUpdate)
throws NoSuchChangeException, OrmException, IOException,
InvalidChangeOperationException, MergeConflictException {
if (!change.currentPatchSetId().equals(patchSetId)) {
throw new InvalidChangeOperationException("patch set is not current");
}
@@ -305,6 +308,9 @@ public class RebaseChange {
.setUploader(uploader.getAccountId())
.setSendMail(sendMail)
.setRunHooks(runHooks);
if (batchRefUpdate != null) {
patchSetInserter.setBatchRefUpdate(batchRefUpdate);
}
final PatchSet.Id newPatchSetId = patchSetInserter.getPatchSetId();
final ChangeMessage cmsg = new ChangeMessage(

View File

@@ -19,8 +19,10 @@ import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.inject.Inject;
import org.eclipse.jgit.lib.BatchRefUpdate;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.transport.ReceiveCommand;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -63,6 +65,14 @@ public class GitReferenceUpdated {
}
}
public void fire(Project.NameKey project, BatchRefUpdate batchRefUpdate) {
for (ReceiveCommand cmd : batchRefUpdate.getCommands()) {
if (cmd.getResult() == ReceiveCommand.Result.OK) {
fire(project, cmd.getRefName(), cmd.getOldId(), cmd.getNewId());
}
}
}
private static class Event implements GitReferenceUpdatedListener.Event {
private final String projectName;
private final String ref;

View File

@@ -76,17 +76,19 @@ import com.google.inject.assistedinject.Assisted;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.BatchRefUpdate;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.NullProgressMonitor;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevFlag;
import org.eclipse.jgit.revwalk.RevSort;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.transport.ReceiveCommand;
import org.joda.time.format.ISODateTimeFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -170,6 +172,7 @@ public class MergeOp {
private Repository repo;
private RevWalk rw;
private RevFlag canMergeFlag;
private ObjectId oldBranchTip;
private CodeReviewCommit branchTip;
private MergeTip mergeTip;
private ObjectInserter inserter;
@@ -257,7 +260,7 @@ public class MergeOp {
openSchema();
openRepository();
RefUpdate branchUpdate = openBranch();
BatchRefUpdate branchUpdate = openBranch();
boolean reopen = false;
ListMultimap<SubmitType, Change> toSubmit =
@@ -276,9 +279,9 @@ public class MergeOp {
logDebug("Reopening branch");
branchUpdate = openBranch();
}
SubmitStrategy strategy = createStrategy(submitType);
SubmitStrategy strategy = createStrategy(submitType, branchUpdate);
MergeTip mergeTip = preMerge(strategy, toMerge.get(submitType));
RefUpdate update = updateBranch(strategy, branchUpdate);
BatchRefUpdate update = updateBranch(strategy, branchUpdate);
reopen = true;
updateChangeStatus(toSubmit.get(submitType), mergeTip);
@@ -414,10 +417,11 @@ public class MergeOp {
return mergeTip;
}
private SubmitStrategy createStrategy(SubmitType submitType)
private SubmitStrategy createStrategy(SubmitType submitType,
BatchRefUpdate branchUpdate)
throws MergeException, NoSuchProjectException {
return submitStrategyFactory.create(submitType, db, repo, rw, inserter,
canMergeFlag, getAlreadyAccepted(branchTip), destBranch);
canMergeFlag, branchUpdate, getAlreadyAccepted(branchTip), destBranch);
}
private void openRepository() throws MergeException, NoSuchProjectException {
@@ -437,16 +441,16 @@ public class MergeOp {
canMergeFlag = rw.newFlag("CAN_MERGE");
}
private RefUpdate openBranch()
private BatchRefUpdate openBranch()
throws MergeException, OrmException, NoSuchChangeException {
try {
RefUpdate branchUpdate = repo.updateRef(destBranch.get());
if (branchUpdate.getOldObjectId() != null) {
branchTip =
(CodeReviewCommit) rw.parseCommit(branchUpdate.getOldObjectId());
BatchRefUpdate branchUpdate = repo.getRefDatabase().newBatchUpdate();
Ref oldRef = repo.getRef(destBranch.get());
oldBranchTip = oldRef != null ? oldRef.getObjectId() : ObjectId.zeroId();
if (!ObjectId.zeroId().equals(oldBranchTip)) {
branchTip = (CodeReviewCommit) rw.parseCommit(oldBranchTip);
} else if (repo.getFullBranch().equals(destBranch.get())) {
branchTip = null;
branchUpdate.setExpectedOldObjectId(ObjectId.zeroId());
} else {
for (ChangeData cd : queryProvider.get().submitted(destBranch)) {
try {
@@ -647,8 +651,8 @@ public class MergeOp {
}
}
private RefUpdate updateBranch(SubmitStrategy strategy,
RefUpdate branchUpdate) throws MergeException {
private BatchRefUpdate updateBranch(SubmitStrategy strategy,
BatchRefUpdate branchUpdate) throws MergeException {
CodeReviewCommit currentTip =
mergeTip != null ? mergeTip.getCurrentTip() : null;
if (branchTip == currentTip) {
@@ -660,7 +664,7 @@ public class MergeOp {
return null;
}
if (RefNames.REFS_CONFIG.equals(branchUpdate.getName())) {
if (RefNames.REFS_CONFIG.equals(destBranch.get())) {
logDebug("Loading new configuration from {}", RefNames.REFS_CONFIG);
try {
ProjectConfig cfg =
@@ -679,25 +683,27 @@ public class MergeOp {
}
branchUpdate.setRefLogIdent(refLogIdent);
branchUpdate.setForceUpdate(false);
branchUpdate.setNewObjectId(currentTip);
branchUpdate.setAllowNonFastForwards(false);
// TODO(dborowitz): This message is also used by all new patch set ref
// updates; find a better wording that works for that case too.
branchUpdate.setRefLogMessage("merged", true);
ReceiveCommand cmd =
new ReceiveCommand(oldBranchTip, currentTip, destBranch.get());
branchUpdate.addCommand(cmd);
try {
RefUpdate.Result result = branchUpdate.update(rw);
logDebug("Update of {}: {}..{} returned status {}",
branchUpdate.getName(), branchUpdate.getOldObjectId(),
branchUpdate.getNewObjectId(), result);
switch (result) {
case NEW:
case FAST_FORWARD:
if (branchUpdate.getResult() == RefUpdate.Result.FAST_FORWARD) {
branchUpdate.execute(rw, NullProgressMonitor.INSTANCE);
logDebug("Executed batch update: {}", branchUpdate);
switch (cmd.getResult()) {
case OK:
if (cmd.getType() == ReceiveCommand.Type.UPDATE) {
tagCache.updateFastForward(destBranch.getParentKey(),
branchUpdate.getName(),
branchUpdate.getOldObjectId(),
destBranch.get(),
oldBranchTip,
currentTip);
}
if (RefNames.REFS_CONFIG.equals(branchUpdate.getName())) {
if (RefNames.REFS_CONFIG.equals(destBranch.get())) {
Project p = destProject.getProject();
projectCache.evict(p);
destProject = projectCache.get(p.getNameKey());
@@ -716,20 +722,26 @@ public class MergeOp {
} else {
msg = "will not retry";
}
throw new IOException(branchUpdate.getResult().name() + ", " + msg);
throw new IOException(cmd.getResult().name() + ", " + msg);
default:
throw new IOException(branchUpdate.getResult().name());
throw new IOException(cmd.getResult().name());
}
} catch (IOException e) {
throw new MergeException("Cannot update " + branchUpdate.getName(), e);
throw new MergeException("Cannot update " + destBranch.get(), e);
}
}
private void fireRefUpdated(RefUpdate branchUpdate) {
logDebug("Firing ref updated hooks for {}", branchUpdate.getName());
private void fireRefUpdated(BatchRefUpdate branchUpdate) {
logDebug("Firing ref updated hooks for {}", destBranch.get());
gitRefUpdated.fire(destBranch.getParentKey(), branchUpdate);
hooks.doRefUpdatedHook(destBranch, branchUpdate,
getAccount(mergeTip.getCurrentTip()));
Account account = getAccount(mergeTip.getCurrentTip());
for (ReceiveCommand cmd : branchUpdate.getCommands()) {
if (cmd.getRefName().equals(destBranch.get())) {
hooks.doRefUpdatedHook(
destBranch, cmd.getOldId(), cmd.getNewId(), account);
break;
}
}
}
private Account getAccount(CodeReviewCommit codeReviewCommit) {

View File

@@ -24,7 +24,6 @@ import com.google.gerrit.reviewdb.client.RevId;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.git.CodeReviewCommit;
import com.google.gerrit.server.git.CommitMergeStatus;
import com.google.gerrit.server.git.MergeConflictException;
@@ -37,8 +36,8 @@ import com.google.gwtorm.server.OrmException;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.transport.ReceiveCommand;
import java.io.IOException;
import java.util.ArrayList;
@@ -50,16 +49,13 @@ import java.util.Map;
public class CherryPick extends SubmitStrategy {
private final PatchSetInfoFactory patchSetInfoFactory;
private final GitReferenceUpdated gitRefUpdated;
private final Map<Change.Id, CodeReviewCommit> newCommits;
CherryPick(SubmitStrategy.Arguments args,
PatchSetInfoFactory patchSetInfoFactory,
GitReferenceUpdated gitRefUpdated) {
PatchSetInfoFactory patchSetInfoFactory) {
super(args);
this.patchSetInfoFactory = patchSetInfoFactory;
this.gitRefUpdated = gitRefUpdated;
this.newCommits = new HashMap<>();
}
@@ -174,8 +170,6 @@ public class CherryPick extends SubmitStrategy {
ps.setUploader(cherryPickUser.getAccountId());
ps.setRevision(new RevId(newCommit.getId().getName()));
RefUpdate ru;
args.db.changes().beginTransaction(n.change().getId());
try {
insertAncestors(args.db, ps.getId(), newCommit);
@@ -191,23 +185,14 @@ public class CherryPick extends SubmitStrategy {
}
args.db.patchSetApprovals().insert(approvals);
ru = args.repo.updateRef(ps.getRefName());
ru.setExpectedOldObjectId(ObjectId.zeroId());
ru.setNewObjectId(newCommit);
ru.disableRefLog();
if (ru.update(args.rw) != RefUpdate.Result.NEW) {
throw new IOException(String.format(
"Failed to create ref %s in %s: %s", ps.getRefName(), n.change()
.getDest().getParentKey().get(), ru.getResult()));
}
args.batchRefUpdate.addCommand(
new ReceiveCommand(ObjectId.zeroId(), newCommit, ps.getRefName()));
args.db.commit();
} finally {
args.db.rollback();
}
gitRefUpdated.fire(n.change().getProject(), ru);
newCommit.copyFrom(n);
newCommit.setStatusCode(CommitMergeStatus.CLEAN_PICK);
newCommit.setControl(args.changeControlFactory.controlFor(n.change(), cherryPickUser));

View File

@@ -87,11 +87,11 @@ public class RebaseIfNecessary extends SubmitStrategy {
IdentifiedUser uploader =
args.identifiedUserFactory.create(args.mergeUtil
.getSubmitter(n).getAccountId());
PatchSet newPatchSet =
rebaseChange.rebase(args.repo, args.rw, args.inserter,
n.getPatchsetId(), n.change(), uploader,
mergeTip.getCurrentTip(), args.mergeUtil,
args.serverIdent.get(), false, false, ValidatePolicy.NONE);
PatchSet newPatchSet = rebaseChange.rebase(args.repo, args.rw,
args.inserter, n.getPatchsetId(), n.change(), uploader,
mergeTip.getCurrentTip(), args.mergeUtil,
args.serverIdent.get(), false, false, ValidatePolicy.NONE,
args.batchRefUpdate);
List<PatchSetApproval> approvals = Lists.newArrayList();
for (PatchSetApproval a : args.approvalsUtil.byPatchSet(args.db,

View File

@@ -30,6 +30,7 @@ import com.google.gerrit.server.index.ChangeIndexer;
import com.google.gerrit.server.project.ChangeControl;
import com.google.inject.Provider;
import org.eclipse.jgit.lib.BatchRefUpdate;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.RefUpdate.Result;
@@ -60,6 +61,7 @@ public abstract class SubmitStrategy {
protected final RevWalk rw;
protected final ObjectInserter inserter;
protected final RevFlag canMergeFlag;
protected final BatchRefUpdate batchRefUpdate;
protected final Set<RevCommit> alreadyAccepted;
protected final Branch.NameKey destBranch;
protected final ApprovalsUtil approvalsUtil;
@@ -71,9 +73,9 @@ public abstract class SubmitStrategy {
Provider<PersonIdent> serverIdent, ReviewDb db,
ChangeControl.GenericFactory changeControlFactory, Repository repo,
RevWalk rw, ObjectInserter inserter, RevFlag canMergeFlag,
Set<RevCommit> alreadyAccepted, Branch.NameKey destBranch,
ApprovalsUtil approvalsUtil, MergeUtil mergeUtil,
ChangeIndexer indexer) {
BatchRefUpdate batchRefUpdate, Set<RevCommit> alreadyAccepted,
Branch.NameKey destBranch, ApprovalsUtil approvalsUtil,
MergeUtil mergeUtil, ChangeIndexer indexer) {
this.identifiedUserFactory = identifiedUserFactory;
this.serverIdent = serverIdent;
this.db = db;
@@ -82,6 +84,7 @@ public abstract class SubmitStrategy {
this.repo = repo;
this.rw = rw;
this.inserter = inserter;
this.batchRefUpdate = batchRefUpdate;
this.canMergeFlag = canMergeFlag;
this.alreadyAccepted = alreadyAccepted;
this.destBranch = destBranch;

View File

@@ -21,7 +21,6 @@ import com.google.gerrit.server.ApprovalsUtil;
import com.google.gerrit.server.GerritPersonIdent;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.changedetail.RebaseChange;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.git.MergeException;
import com.google.gerrit.server.git.MergeUtil;
import com.google.gerrit.server.index.ChangeIndexer;
@@ -34,6 +33,7 @@ import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import org.eclipse.jgit.lib.BatchRefUpdate;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Repository;
@@ -55,7 +55,6 @@ public class SubmitStrategyFactory {
private final Provider<PersonIdent> myIdent;
private final ChangeControl.GenericFactory changeControlFactory;
private final PatchSetInfoFactory patchSetInfoFactory;
private final GitReferenceUpdated gitRefUpdated;
private final RebaseChange rebaseChange;
private final ProjectCache projectCache;
private final ApprovalsUtil approvalsUtil;
@@ -68,7 +67,7 @@ public class SubmitStrategyFactory {
@GerritPersonIdent Provider<PersonIdent> myIdent,
final ChangeControl.GenericFactory changeControlFactory,
final PatchSetInfoFactory patchSetInfoFactory,
final GitReferenceUpdated gitRefUpdated, final RebaseChange rebaseChange,
final RebaseChange rebaseChange,
final ProjectCache projectCache,
final ApprovalsUtil approvalsUtil,
final MergeUtil.Factory mergeUtilFactory,
@@ -77,7 +76,6 @@ public class SubmitStrategyFactory {
this.myIdent = myIdent;
this.changeControlFactory = changeControlFactory;
this.patchSetInfoFactory = patchSetInfoFactory;
this.gitRefUpdated = gitRefUpdated;
this.rebaseChange = rebaseChange;
this.projectCache = projectCache;
this.approvalsUtil = approvalsUtil;
@@ -85,20 +83,19 @@ public class SubmitStrategyFactory {
this.indexer = indexer;
}
public SubmitStrategy create(final SubmitType submitType, final ReviewDb db,
final Repository repo, final RevWalk rw, final ObjectInserter inserter,
final RevFlag canMergeFlag, final Set<RevCommit> alreadyAccepted,
final Branch.NameKey destBranch)
public SubmitStrategy create(SubmitType submitType, ReviewDb db,
Repository repo, RevWalk rw, ObjectInserter inserter,
RevFlag canMergeFlag, BatchRefUpdate batchRefUpdated,
Set<RevCommit> alreadyAccepted, Branch.NameKey destBranch)
throws MergeException, NoSuchProjectException {
ProjectState project = getProject(destBranch);
final SubmitStrategy.Arguments args =
new SubmitStrategy.Arguments(identifiedUserFactory, myIdent, db,
changeControlFactory, repo, rw, inserter, canMergeFlag,
alreadyAccepted, destBranch,approvalsUtil,
mergeUtilFactory.create(project), indexer);
SubmitStrategy.Arguments args = new SubmitStrategy.Arguments(
identifiedUserFactory, myIdent, db, changeControlFactory, repo, rw,
inserter, canMergeFlag, batchRefUpdated, alreadyAccepted, destBranch,
approvalsUtil, mergeUtilFactory.create(project), indexer);
switch (submitType) {
case CHERRY_PICK:
return new CherryPick(args, patchSetInfoFactory, gitRefUpdated);
return new CherryPick(args, patchSetInfoFactory);
case FAST_FORWARD_ONLY:
return new FastForwardOnly(args);
case MERGE_ALWAYS:

View File

@@ -119,7 +119,7 @@ class ConflictsPredicate extends OrPredicate<ChangeData> {
SubmitStrategy strategy =
args.submitStrategyFactory.create(submitType,
db.get(), repo, rw, null, canMergeFlag,
getAlreadyAccepted(repo, rw, commit),
null, getAlreadyAccepted(repo, rw, commit),
otherChange.getDest());
CodeReviewCommit otherCommit =
(CodeReviewCommit) rw.parseCommit(other);