Convert MergeUtil to use all non-static methods

The signatures in MergeUtil required passing in a fair number of
arguments that could just as well be injected, so inject them instead.
Additionally, use an assisted factory to inject the relevant project,
or useContentMerge argument.

Change-Id: I6b76922865d1aa1b5ae8ead2c2b131ea4739615a
This commit is contained in:
Dave Borowitz
2013-03-12 16:34:22 -07:00
parent c4bb89050a
commit ac2095659a
11 changed files with 165 additions and 177 deletions

View File

@@ -73,6 +73,7 @@ public class RebaseChange {
private final RebasedPatchSetSender.Factory rebasedPatchSetSenderFactory; private final RebasedPatchSetSender.Factory rebasedPatchSetSenderFactory;
private final ChangeHookRunner hooks; private final ChangeHookRunner hooks;
private final ApprovalsUtil approvalsUtil; private final ApprovalsUtil approvalsUtil;
private final MergeUtil.Factory mergeUtilFactory;
@Inject @Inject
RebaseChange(final ChangeControl.Factory changeControlFactory, RebaseChange(final ChangeControl.Factory changeControlFactory,
@@ -81,7 +82,8 @@ public class RebaseChange {
final GitRepositoryManager gitManager, final GitRepositoryManager gitManager,
final GitReferenceUpdated gitRefUpdated, final GitReferenceUpdated gitRefUpdated,
final RebasedPatchSetSender.Factory rebasedPatchSetSenderFactory, final RebasedPatchSetSender.Factory rebasedPatchSetSenderFactory,
final ChangeHookRunner hooks, final ApprovalsUtil approvalsUtil) { final ChangeHookRunner hooks, final ApprovalsUtil approvalsUtil,
final MergeUtil.Factory mergeUtilFactory) {
this.changeControlFactory = changeControlFactory; this.changeControlFactory = changeControlFactory;
this.patchSetInfoFactory = patchSetInfoFactory; this.patchSetInfoFactory = patchSetInfoFactory;
this.db = db; this.db = db;
@@ -91,6 +93,7 @@ public class RebaseChange {
this.rebasedPatchSetSenderFactory = rebasedPatchSetSenderFactory; this.rebasedPatchSetSenderFactory = rebasedPatchSetSenderFactory;
this.hooks = hooks; this.hooks = hooks;
this.approvalsUtil = approvalsUtil; this.approvalsUtil = approvalsUtil;
this.mergeUtilFactory = mergeUtilFactory;
} }
/** /**
@@ -149,7 +152,8 @@ public class RebaseChange {
final PatchSet newPatchSet = final PatchSet newPatchSet =
rebase(git, rw, inserter, patchSetId, change, uploader, baseCommit, rebase(git, rw, inserter, patchSetId, change, uploader, baseCommit,
true); mergeUtilFactory.create(
changeControl.getProjectControl().getProjectState(), true));
final Set<Account.Id> oldReviewers = Sets.newHashSet(); final Set<Account.Id> oldReviewers = Sets.newHashSet();
final Set<Account.Id> oldCC = Sets.newHashSet(); final Set<Account.Id> oldCC = Sets.newHashSet();
@@ -290,7 +294,7 @@ public class RebaseChange {
* @param chg the change that should be rebased * @param chg the change that should be rebased
* @param uploader the user that creates the rebased patch set * @param uploader the user that creates the rebased patch set
* @param baseCommit the commit that should be the new base * @param baseCommit the commit that should be the new base
* @param useContentMerge flag that decides if content merge should be done * @param mergeUtil merge utilities for the destination project
* @return the new patch set which is based on the given base commit * @return the new patch set which is based on the given base commit
* @throws NoSuchChangeException thrown if the change to which the patch set * @throws NoSuchChangeException thrown if the change to which the patch set
* belongs does not exist or is not visible to the user * belongs does not exist or is not visible to the user
@@ -301,7 +305,7 @@ public class RebaseChange {
public PatchSet rebase(final Repository git, final RevWalk revWalk, public PatchSet rebase(final Repository git, final RevWalk revWalk,
final ObjectInserter inserter, final PatchSet.Id patchSetId, final ObjectInserter inserter, final PatchSet.Id patchSetId,
final Change chg, final Account.Id uploader, final RevCommit baseCommit, final Change chg, final Account.Id uploader, final RevCommit baseCommit,
final boolean useContentMerge) throws NoSuchChangeException, final MergeUtil mergeUtil) throws NoSuchChangeException,
OrmException, IOException, InvalidChangeOperationException, OrmException, IOException, InvalidChangeOperationException,
PathConflictException { PathConflictException {
Change change = chg; Change change = chg;
@@ -309,9 +313,8 @@ public class RebaseChange {
final RevCommit rebasedCommit; final RevCommit rebasedCommit;
ObjectId oldId = ObjectId.fromString(originalPatchSet.getRevision().get()); ObjectId oldId = ObjectId.fromString(originalPatchSet.getRevision().get());
ObjectId newId = ObjectId newId = rebaseCommit(git, inserter, revWalk.parseCommit(oldId),
rebaseCommit(git, inserter, revWalk.parseCommit(oldId), baseCommit, baseCommit, mergeUtil, myIdent);
useContentMerge, myIdent);
rebasedCommit = revWalk.parseCommit(newId); rebasedCommit = revWalk.parseCommit(newId);
@@ -400,15 +403,15 @@ public class RebaseChange {
* @param inserter inserter to handle new trees and blobs * @param inserter inserter to handle new trees and blobs
* @param original The commit to rebase * @param original The commit to rebase
* @param base Base to rebase against * @param base Base to rebase against
* @param useContentMerge flag to decide if content merge should be done * @param mergeUtil merge utilities for the destination project
* @param committerIdent committer identity * @param committerIdent committer identity
* @return the id of the rebased commit * @return the id of the rebased commit
* @throws IOException Merged failed * @throws IOException Merged failed
* @throws PathConflictException the rebase failed due to a path conflict * @throws PathConflictException the rebase failed due to a path conflict
*/ */
private static ObjectId rebaseCommit(final Repository git, private ObjectId rebaseCommit(final Repository git,
final ObjectInserter inserter, final RevCommit original, final ObjectInserter inserter, final RevCommit original,
final RevCommit base, final boolean useContentMerge, final RevCommit base, final MergeUtil mergeUtil,
final PersonIdent committerIdent) throws IOException, final PersonIdent committerIdent) throws IOException,
PathConflictException { PathConflictException {
@@ -418,7 +421,7 @@ public class RebaseChange {
throw new IOException("Change is already up to date."); throw new IOException("Change is already up to date.");
} }
final ThreeWayMerger merger = MergeUtil.newThreeWayMerger(git, inserter, useContentMerge); final ThreeWayMerger merger = mergeUtil.newThreeWayMerger(git, inserter);
merger.setBase(parentCommit); merger.setBase(parentCommit);
merger.merge(original, base); merger.merge(original, base);

View File

@@ -70,6 +70,7 @@ import com.google.gerrit.server.git.ChangeCache;
import com.google.gerrit.server.git.ChangeMergeQueue; import com.google.gerrit.server.git.ChangeMergeQueue;
import com.google.gerrit.server.git.GitModule; import com.google.gerrit.server.git.GitModule;
import com.google.gerrit.server.git.MergeQueue; import com.google.gerrit.server.git.MergeQueue;
import com.google.gerrit.server.git.MergeUtil;
import com.google.gerrit.server.git.NotesBranchUtil; import com.google.gerrit.server.git.NotesBranchUtil;
import com.google.gerrit.server.git.ReloadSubmitQueueOp; import com.google.gerrit.server.git.ReloadSubmitQueueOp;
import com.google.gerrit.server.git.TagCache; import com.google.gerrit.server.git.TagCache;
@@ -180,6 +181,7 @@ public class GerritGlobalModule extends FactoryModule {
factory(InternalUser.Factory.class); factory(InternalUser.Factory.class);
factory(MergedSender.Factory.class); factory(MergedSender.Factory.class);
factory(MergeFailSender.Factory.class); factory(MergeFailSender.Factory.class);
factory(MergeUtil.Factory.class);
factory(PerformCreateGroup.Factory.class); factory(PerformCreateGroup.Factory.class);
factory(PerformRenameGroup.Factory.class); factory(PerformRenameGroup.Factory.class);
factory(ProjectNode.Factory.class); factory(ProjectNode.Factory.class);

View File

@@ -14,17 +14,7 @@
package com.google.gerrit.server.git; package com.google.gerrit.server.git;
import static com.google.gerrit.server.git.MergeUtil.canCherryPick;
import static com.google.gerrit.server.git.MergeUtil.createCherryPickCommitMessage;
import static com.google.gerrit.server.git.MergeUtil.createCherryPickFromCommit;
import static com.google.gerrit.server.git.MergeUtil.getSubmitter;
import static com.google.gerrit.server.git.MergeUtil.hasMissingDependencies;
import static com.google.gerrit.server.git.MergeUtil.markCleanMerges;
import static com.google.gerrit.server.git.MergeUtil.mergeOneCommit;
import static com.google.gerrit.server.git.MergeUtil.getApprovalsForCommit;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.gerrit.common.data.LabelTypes;
import com.google.gerrit.reviewdb.client.Change; import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet; import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.PatchSetAncestor; import com.google.gerrit.reviewdb.client.PatchSetAncestor;
@@ -35,7 +25,6 @@ import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated; import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.patch.PatchSetInfoFactory; import com.google.gerrit.server.patch.PatchSetInfoFactory;
import com.google.gwtorm.server.OrmException; import com.google.gwtorm.server.OrmException;
import com.google.inject.Provider;
import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.lib.PersonIdent;
@@ -52,20 +41,15 @@ import java.util.Map;
public class CherryPick extends SubmitStrategy { public class CherryPick extends SubmitStrategy {
private final PatchSetInfoFactory patchSetInfoFactory; private final PatchSetInfoFactory patchSetInfoFactory;
private final Provider<String> urlProvider;
private final LabelTypes labelTypes;
private final GitReferenceUpdated gitRefUpdated; private final GitReferenceUpdated gitRefUpdated;
private final Map<Change.Id, CodeReviewCommit> newCommits; private final Map<Change.Id, CodeReviewCommit> newCommits;
CherryPick(final SubmitStrategy.Arguments args, CherryPick(final SubmitStrategy.Arguments args,
final PatchSetInfoFactory patchSetInfoFactory, final PatchSetInfoFactory patchSetInfoFactory,
final Provider<String> urlProvider, final LabelTypes labelTypes,
final GitReferenceUpdated gitRefUpdated) { final GitReferenceUpdated gitRefUpdated) {
super(args); super(args);
this.patchSetInfoFactory = patchSetInfoFactory; this.patchSetInfoFactory = patchSetInfoFactory;
this.urlProvider = urlProvider;
this.labelTypes = labelTypes;
this.gitRefUpdated = gitRefUpdated; this.gitRefUpdated = gitRefUpdated;
this.newCommits = new HashMap<Change.Id, CodeReviewCommit>(); this.newCommits = new HashMap<Change.Id, CodeReviewCommit>();
} }
@@ -112,18 +96,17 @@ public class CherryPick extends SubmitStrategy {
// by an equivalent merge with a different first parent. So // by an equivalent merge with a different first parent. So
// instead behave as though MERGE_IF_NECESSARY was configured. // instead behave as though MERGE_IF_NECESSARY was configured.
// //
if (!hasMissingDependencies(args.mergeSorter, n)) { if (!args.mergeUtil.hasMissingDependencies(args.mergeSorter, n)) {
if (args.rw.isMergedInto(newMergeTip, n)) { if (args.rw.isMergedInto(newMergeTip, n)) {
newMergeTip = n; newMergeTip = n;
} else { } else {
newMergeTip = newMergeTip =
mergeOneCommit(args.db, args.identifiedUserFactory, args.mergeUtil.mergeOneCommit(args.myIdent, args.repo,
args.myIdent, args.repo, args.rw, args.inserter, args.rw, args.inserter, args.canMergeFlag,
args.canMergeFlag, args.useContentMerge, args.destBranch, args.destBranch, newMergeTip, n);
newMergeTip, n);
} }
final PatchSetApproval submitApproval = final PatchSetApproval submitApproval =
markCleanMerges(args.db, args.rw, args.canMergeFlag, args.mergeUtil.markCleanMerges(args.rw, args.canMergeFlag,
newMergeTip, args.alreadyAccepted); newMergeTip, args.alreadyAccepted);
setRefLogIdent(submitApproval); setRefLogIdent(submitApproval);
@@ -150,7 +133,7 @@ public class CherryPick extends SubmitStrategy {
args.rw.parseBody(n); args.rw.parseBody(n);
final PatchSetApproval submitAudit = final PatchSetApproval submitAudit =
getSubmitter(args.db, n.change.currentPatchSetId()); args.mergeUtil.getSubmitter(n.change.currentPatchSetId());
PersonIdent cherryPickCommitterIdent = null; PersonIdent cherryPickCommitterIdent = null;
if (submitAudit != null) { if (submitAudit != null) {
@@ -162,13 +145,11 @@ public class CherryPick extends SubmitStrategy {
cherryPickCommitterIdent = args.myIdent; cherryPickCommitterIdent = args.myIdent;
} }
final String cherryPickCmtMsg = final String cherryPickCmtMsg = args.mergeUtil.createCherryPickCommitMessage(n);
createCherryPickCommitMessage(n, labelTypes, urlProvider, args.db,
args.identifiedUserFactory);
final CodeReviewCommit newCommit = final CodeReviewCommit newCommit =
createCherryPickFromCommit(args.repo, args.inserter, mergeTip, n, args.mergeUtil.createCherryPickFromCommit(args.repo, args.inserter, mergeTip, n,
cherryPickCommitterIdent, cherryPickCmtMsg, args.rw, args.useContentMerge); cherryPickCommitterIdent, cherryPickCmtMsg, args.rw);
if (newCommit == null) { if (newCommit == null) {
return null; return null;
@@ -187,7 +168,7 @@ public class CherryPick extends SubmitStrategy {
args.db.changes().update(Collections.singletonList(n.change)); args.db.changes().update(Collections.singletonList(n.change));
final List<PatchSetApproval> approvals = Lists.newArrayList(); final List<PatchSetApproval> approvals = Lists.newArrayList();
for (PatchSetApproval a : getApprovalsForCommit(args.db, n)) { for (PatchSetApproval a : args.mergeUtil.getApprovalsForCommit(n)) {
approvals.add(new PatchSetApproval(ps.getId(), a)); approvals.add(new PatchSetApproval(ps.getId(), a));
} }
args.db.patchSetApprovals().insert(approvals); args.db.patchSetApprovals().insert(approvals);
@@ -233,7 +214,7 @@ public class CherryPick extends SubmitStrategy {
@Override @Override
public boolean dryRun(final CodeReviewCommit mergeTip, public boolean dryRun(final CodeReviewCommit mergeTip,
final CodeReviewCommit toMerge) throws MergeException { final CodeReviewCommit toMerge) throws MergeException {
return canCherryPick(args.mergeSorter, args.repo, args.useContentMerge, return args.mergeUtil.canCherryPick(args.mergeSorter, args.repo,
mergeTip, args.rw, toMerge); mergeTip, args.rw, toMerge);
} }
} }

View File

@@ -14,11 +14,6 @@
package com.google.gerrit.server.git; package com.google.gerrit.server.git;
import static com.google.gerrit.server.git.MergeUtil.canFastForward;
import static com.google.gerrit.server.git.MergeUtil.getFirstFastForward;
import static com.google.gerrit.server.git.MergeUtil.markCleanMerges;
import static com.google.gerrit.server.git.MergeUtil.reduceToMinimalMerge;
import com.google.gerrit.reviewdb.client.PatchSetApproval; import com.google.gerrit.reviewdb.client.PatchSetApproval;
import java.util.List; import java.util.List;
@@ -32,9 +27,9 @@ public class FastForwardOnly extends SubmitStrategy {
@Override @Override
protected CodeReviewCommit _run(final CodeReviewCommit mergeTip, protected CodeReviewCommit _run(final CodeReviewCommit mergeTip,
final List<CodeReviewCommit> toMerge) throws MergeException { final List<CodeReviewCommit> toMerge) throws MergeException {
reduceToMinimalMerge(args.mergeSorter, toMerge); args.mergeUtil.reduceToMinimalMerge(args.mergeSorter, toMerge);
final CodeReviewCommit newMergeTip = final CodeReviewCommit newMergeTip =
getFirstFastForward(mergeTip, args.rw, toMerge); args.mergeUtil.getFirstFastForward(mergeTip, args.rw, toMerge);
while (!toMerge.isEmpty()) { while (!toMerge.isEmpty()) {
final CodeReviewCommit n = toMerge.remove(0); final CodeReviewCommit n = toMerge.remove(0);
@@ -42,7 +37,7 @@ public class FastForwardOnly extends SubmitStrategy {
} }
final PatchSetApproval submitApproval = final PatchSetApproval submitApproval =
markCleanMerges(args.db, args.rw, args.canMergeFlag, newMergeTip, args.mergeUtil.markCleanMerges(args.rw, args.canMergeFlag, newMergeTip,
args.alreadyAccepted); args.alreadyAccepted);
setRefLogIdent(submitApproval); setRefLogIdent(submitApproval);
@@ -56,6 +51,7 @@ public class FastForwardOnly extends SubmitStrategy {
public boolean dryRun(final CodeReviewCommit mergeTip, public boolean dryRun(final CodeReviewCommit mergeTip,
final CodeReviewCommit toMerge) throws MergeException { final CodeReviewCommit toMerge) throws MergeException {
return canFastForward(args.mergeSorter, mergeTip, args.rw, toMerge); return args.mergeUtil.canFastForward(args.mergeSorter, mergeTip, args.rw,
toMerge);
} }
} }

View File

@@ -14,11 +14,6 @@
package com.google.gerrit.server.git; package com.google.gerrit.server.git;
import static com.google.gerrit.server.git.MergeUtil.markCleanMerges;
import static com.google.gerrit.server.git.MergeUtil.canMerge;
import static com.google.gerrit.server.git.MergeUtil.mergeOneCommit;
import static com.google.gerrit.server.git.MergeUtil.reduceToMinimalMerge;
import com.google.gerrit.reviewdb.client.PatchSetApproval; import com.google.gerrit.reviewdb.client.PatchSetApproval;
import java.util.List; import java.util.List;
@@ -32,19 +27,18 @@ public class MergeAlways extends SubmitStrategy {
@Override @Override
protected CodeReviewCommit _run(final CodeReviewCommit mergeTip, protected CodeReviewCommit _run(final CodeReviewCommit mergeTip,
final List<CodeReviewCommit> toMerge) throws MergeException { final List<CodeReviewCommit> toMerge) throws MergeException {
reduceToMinimalMerge(args.mergeSorter, toMerge); args.mergeUtil.reduceToMinimalMerge(args.mergeSorter, toMerge);
CodeReviewCommit newMergeTip = mergeTip; CodeReviewCommit newMergeTip = mergeTip;
while (!toMerge.isEmpty()) { while (!toMerge.isEmpty()) {
newMergeTip = newMergeTip =
mergeOneCommit(args.db, args.identifiedUserFactory, args.myIdent, args.mergeUtil.mergeOneCommit(args.myIdent, args.repo, args.rw,
args.repo, args.rw, args.inserter, args.canMergeFlag, args.inserter, args.canMergeFlag, args.destBranch, mergeTip,
args.useContentMerge, args.destBranch, mergeTip,
toMerge.remove(0)); toMerge.remove(0));
} }
final PatchSetApproval submitApproval = final PatchSetApproval submitApproval =
markCleanMerges(args.db, args.rw, args.canMergeFlag, newMergeTip, args.mergeUtil.markCleanMerges(args.rw, args.canMergeFlag, newMergeTip,
args.alreadyAccepted); args.alreadyAccepted);
setRefLogIdent(submitApproval); setRefLogIdent(submitApproval);
@@ -54,7 +48,7 @@ public class MergeAlways extends SubmitStrategy {
@Override @Override
public boolean dryRun(final CodeReviewCommit mergeTip, public boolean dryRun(final CodeReviewCommit mergeTip,
final CodeReviewCommit toMerge) throws MergeException { final CodeReviewCommit toMerge) throws MergeException {
return canMerge(args.mergeSorter, args.repo, args.useContentMerge, return args.mergeUtil.canMerge(args.mergeSorter, args.repo, mergeTip,
mergeTip, toMerge); toMerge);
} }
} }

View File

@@ -14,13 +14,6 @@
package com.google.gerrit.server.git; package com.google.gerrit.server.git;
import static com.google.gerrit.server.git.MergeUtil.canFastForward;
import static com.google.gerrit.server.git.MergeUtil.canMerge;
import static com.google.gerrit.server.git.MergeUtil.getFirstFastForward;
import static com.google.gerrit.server.git.MergeUtil.markCleanMerges;
import static com.google.gerrit.server.git.MergeUtil.mergeOneCommit;
import static com.google.gerrit.server.git.MergeUtil.reduceToMinimalMerge;
import com.google.gerrit.reviewdb.client.PatchSetApproval; import com.google.gerrit.reviewdb.client.PatchSetApproval;
import java.util.List; import java.util.List;
@@ -34,22 +27,20 @@ public class MergeIfNecessary extends SubmitStrategy {
@Override @Override
protected CodeReviewCommit _run(final CodeReviewCommit mergeTip, protected CodeReviewCommit _run(final CodeReviewCommit mergeTip,
final List<CodeReviewCommit> toMerge) throws MergeException { final List<CodeReviewCommit> toMerge) throws MergeException {
reduceToMinimalMerge(args.mergeSorter, toMerge); args.mergeUtil.reduceToMinimalMerge(args.mergeSorter, toMerge);
CodeReviewCommit newMergeTip = CodeReviewCommit newMergeTip =
getFirstFastForward(mergeTip, args.rw, toMerge); args.mergeUtil.getFirstFastForward(mergeTip, args.rw, toMerge);
// For every other commit do a pair-wise merge. // For every other commit do a pair-wise merge.
while (!toMerge.isEmpty()) { while (!toMerge.isEmpty()) {
newMergeTip = newMergeTip =
mergeOneCommit(args.db, args.identifiedUserFactory, args.myIdent, args.mergeUtil.mergeOneCommit(args.myIdent, args.repo, args.rw,
args.repo, args.rw, args.inserter, args.canMergeFlag, args.inserter, args.canMergeFlag, args.destBranch, mergeTip,
args.useContentMerge, args.destBranch, mergeTip,
toMerge.remove(0)); toMerge.remove(0));
} }
final PatchSetApproval submitApproval = final PatchSetApproval submitApproval = args.mergeUtil.markCleanMerges(
markCleanMerges(args.db, args.rw, args.canMergeFlag, newMergeTip, args.rw, args.canMergeFlag, newMergeTip, args.alreadyAccepted);
args.alreadyAccepted);
setRefLogIdent(submitApproval); setRefLogIdent(submitApproval);
return newMergeTip; return newMergeTip;
@@ -58,8 +49,9 @@ public class MergeIfNecessary extends SubmitStrategy {
@Override @Override
public boolean dryRun(final CodeReviewCommit mergeTip, public boolean dryRun(final CodeReviewCommit mergeTip,
final CodeReviewCommit toMerge) throws MergeException { final CodeReviewCommit toMerge) throws MergeException {
return canFastForward(args.mergeSorter, mergeTip, args.rw, toMerge) return args.mergeUtil.canFastForward(
|| canMerge(args.mergeSorter, args.repo, args.useContentMerge, args.mergeSorter, mergeTip, args.rw, toMerge)
mergeTip, toMerge); || args.mergeUtil.canMerge(
args.mergeSorter, args.repo, mergeTip, toMerge);
} }
} }

View File

@@ -391,8 +391,7 @@ public class MergeOp {
private SubmitStrategy createStrategy(final SubmitType submitType) private SubmitStrategy createStrategy(final SubmitType submitType)
throws MergeException, NoSuchProjectException { throws MergeException, NoSuchProjectException {
return submitStrategyFactory.create(submitType, db, repo, rw, inserter, return submitStrategyFactory.create(submitType, db, repo, rw, inserter,
canMergeFlag, getAlreadyAccepted(branchTip), destBranch, canMergeFlag, getAlreadyAccepted(branchTip), destBranch);
destProject.isUseContentMerge());
} }
private void openRepository() throws MergeException { private void openRepository() throws MergeException {

View File

@@ -15,7 +15,6 @@
package com.google.gerrit.server.git; package com.google.gerrit.server.git;
import com.google.gerrit.common.data.LabelType; import com.google.gerrit.common.data.LabelType;
import com.google.gerrit.common.data.LabelTypes;
import com.google.gerrit.reviewdb.client.Account; import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.ApprovalCategory; import com.google.gerrit.reviewdb.client.ApprovalCategory;
import com.google.gerrit.reviewdb.client.Branch; import com.google.gerrit.reviewdb.client.Branch;
@@ -23,8 +22,12 @@ import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.PatchSetApproval; import com.google.gerrit.reviewdb.client.PatchSetApproval;
import com.google.gerrit.reviewdb.server.ReviewDb; import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.IdentifiedUser; import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.config.CanonicalWebUrl;
import com.google.gerrit.server.project.ProjectState;
import com.google.gwtorm.server.OrmException; import com.google.gwtorm.server.OrmException;
import com.google.inject.Provider; import com.google.inject.Provider;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.AssistedInject;
import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.errors.MissingObjectException;
@@ -64,9 +67,16 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.TimeZone; import java.util.TimeZone;
import javax.annotation.Nullable;
public class MergeUtil { public class MergeUtil {
private static final Logger log = LoggerFactory.getLogger(MergeUtil.class); private static final Logger log = LoggerFactory.getLogger(MergeUtil.class);
public static interface Factory {
MergeUtil create(ProjectState project);
MergeUtil create(ProjectState project, boolean useContentMerge);
}
private static final String R_HEADS_MASTER = private static final String R_HEADS_MASTER =
Constants.R_HEADS + Constants.MASTER; Constants.R_HEADS + Constants.MASTER;
@@ -78,7 +88,35 @@ public class MergeUtil {
private static final FooterKey REVIEWED_ON = new FooterKey("Reviewed-on"); private static final FooterKey REVIEWED_ON = new FooterKey("Reviewed-on");
private static final FooterKey CHANGE_ID = new FooterKey("Change-Id"); private static final FooterKey CHANGE_ID = new FooterKey("Change-Id");
public static CodeReviewCommit getFirstFastForward( private final Provider<ReviewDb> db;
private final IdentifiedUser.GenericFactory identifiedUserFactory;
private final Provider<String> urlProvider;
private final ProjectState project;
private final boolean useContentMerge;
@AssistedInject
MergeUtil(final Provider<ReviewDb> db,
final IdentifiedUser.GenericFactory identifiedUserFactory,
@CanonicalWebUrl @Nullable final Provider<String> urlProvider,
@Assisted final ProjectState project) {
this(db, identifiedUserFactory, urlProvider, project,
project.isUseContentMerge());
}
@AssistedInject
MergeUtil(final Provider<ReviewDb> db,
final IdentifiedUser.GenericFactory identifiedUserFactory,
@CanonicalWebUrl @Nullable final Provider<String> urlProvider,
@Assisted final ProjectState project,
@Assisted boolean useContentMerge) {
this.db = db;
this.identifiedUserFactory = identifiedUserFactory;
this.urlProvider = urlProvider;
this.project = project;
this.useContentMerge = useContentMerge;
}
public CodeReviewCommit getFirstFastForward(
final CodeReviewCommit mergeTip, final RevWalk rw, final CodeReviewCommit mergeTip, final RevWalk rw,
final List<CodeReviewCommit> toMerge) throws MergeException { final List<CodeReviewCommit> toMerge) throws MergeException {
for (final Iterator<CodeReviewCommit> i = toMerge.iterator(); i.hasNext();) { for (final Iterator<CodeReviewCommit> i = toMerge.iterator(); i.hasNext();) {
@@ -95,7 +133,7 @@ public class MergeUtil {
return mergeTip; return mergeTip;
} }
public static void reduceToMinimalMerge(final MergeSorter mergeSorter, public void reduceToMinimalMerge(final MergeSorter mergeSorter,
final List<CodeReviewCommit> toSort) throws MergeException { final List<CodeReviewCommit> toSort) throws MergeException {
final Collection<CodeReviewCommit> heads; final Collection<CodeReviewCommit> heads;
try { try {
@@ -114,6 +152,10 @@ public class MergeUtil {
}); });
} }
public PatchSetApproval getSubmitter(final PatchSet.Id c) {
return getSubmitter(db.get(), c);
}
public static PatchSetApproval getSubmitter(final ReviewDb reviewDb, public static PatchSetApproval getSubmitter(final ReviewDb reviewDb,
final PatchSet.Id c) { final PatchSet.Id c) {
if (c == null) { if (c == null) {
@@ -137,13 +179,12 @@ public class MergeUtil {
return submitter; return submitter;
} }
public static CodeReviewCommit createCherryPickFromCommit(Repository repo, public CodeReviewCommit createCherryPickFromCommit(Repository repo,
ObjectInserter inserter, CodeReviewCommit mergeTip, CodeReviewCommit originalCommit, ObjectInserter inserter, CodeReviewCommit mergeTip, CodeReviewCommit originalCommit,
PersonIdent cherryPickCommitterIdent, String commitMsg, RevWalk rw, PersonIdent cherryPickCommitterIdent, String commitMsg, RevWalk rw)
Boolean useContentMerge) throws MissingObjectException, IncorrectObjectTypeException, IOException { throws MissingObjectException, IncorrectObjectTypeException, IOException {
final ThreeWayMerger m = final ThreeWayMerger m = newThreeWayMerger(repo, inserter);
newThreeWayMerger(repo, inserter, useContentMerge);
m.setBase(originalCommit.getParent(0)); m.setBase(originalCommit.getParent(0));
if (m.merge(mergeTip, originalCommit)) { if (m.merge(mergeTip, originalCommit)) {
@@ -166,9 +207,7 @@ public class MergeUtil {
} }
} }
public static String createCherryPickCommitMessage(final CodeReviewCommit n, public String createCherryPickCommitMessage(final CodeReviewCommit n) {
final LabelTypes labelTypes, final Provider<String> urlProvider,
final ReviewDb db, final IdentifiedUser.GenericFactory identifiedUserFactory) {
final List<FooterLine> footers = n.getFooterLines(); final List<FooterLine> footers = n.getFooterLines();
final StringBuilder msgbuf = new StringBuilder(); final StringBuilder msgbuf = new StringBuilder();
msgbuf.append(n.getFullMessage()); msgbuf.append(n.getFullMessage());
@@ -208,7 +247,7 @@ public class MergeUtil {
PatchSetApproval submitAudit = null; PatchSetApproval submitAudit = null;
for (final PatchSetApproval a : getApprovalsForCommit(db, n)) { for (final PatchSetApproval a : getApprovalsForCommit(n)) {
if (a.getValue() <= 0) { if (a.getValue() <= 0) {
// Negative votes aren't counted. // Negative votes aren't counted.
continue; continue;
@@ -256,7 +295,8 @@ public class MergeUtil {
} else if (VRIF.equals(a.getCategoryId())) { } else if (VRIF.equals(a.getCategoryId())) {
tag = "Tested-by"; tag = "Tested-by";
} else { } else {
final LabelType lt = labelTypes.byId(a.getCategoryId().get()); final LabelType lt =
project.getLabelTypes().byId(a.getCategoryId().get());
if (lt == null) { if (lt == null) {
// TODO: Support arbitrary labels. // TODO: Support arbitrary labels.
continue; continue;
@@ -275,10 +315,10 @@ public class MergeUtil {
return msgbuf.toString(); return msgbuf.toString();
} }
public static List<PatchSetApproval> getApprovalsForCommit(final ReviewDb db, final CodeReviewCommit n) { public List<PatchSetApproval> getApprovalsForCommit(final CodeReviewCommit n) {
try { try {
List<PatchSetApproval> approvalList = List<PatchSetApproval> approvalList =
db.patchSetApprovals().byPatchSet(n.patchsetId).toList(); db.get().patchSetApprovals().byPatchSet(n.patchsetId).toList();
Collections.sort(approvalList, new Comparator<PatchSetApproval>() { Collections.sort(approvalList, new Comparator<PatchSetApproval>() {
@Override @Override
public int compare(final PatchSetApproval a, final PatchSetApproval b) { public int compare(final PatchSetApproval a, final PatchSetApproval b) {
@@ -311,13 +351,11 @@ public class MergeUtil {
return false; return false;
} }
public static PersonIdent computeMergeCommitAuthor(final ReviewDb reviewDb, public PersonIdent computeMergeCommitAuthor(final PersonIdent myIdent,
final IdentifiedUser.GenericFactory identifiedUserFactory, final RevWalk rw, final List<CodeReviewCommit> codeReviewCommits) {
final PersonIdent myIdent, final RevWalk rw,
final List<CodeReviewCommit> codeReviewCommits) {
PatchSetApproval submitter = null; PatchSetApproval submitter = null;
for (final CodeReviewCommit c : codeReviewCommits) { for (final CodeReviewCommit c : codeReviewCommits) {
PatchSetApproval s = getSubmitter(reviewDb, c.patchsetId); PatchSetApproval s = getSubmitter(c.patchsetId);
if (submitter == null if (submitter == null
|| (s != null && s.getGranted().compareTo(submitter.getGranted()) > 0)) { || (s != null && s.getGranted().compareTo(submitter.getGranted()) > 0)) {
submitter = s; submitter = s;
@@ -360,16 +398,15 @@ public class MergeUtil {
return authorIdent; return authorIdent;
} }
public static boolean canMerge(final MergeSorter mergeSorter, public boolean canMerge(final MergeSorter mergeSorter,
final Repository repo, final boolean useContentMerge, final Repository repo, final CodeReviewCommit mergeTip,
final CodeReviewCommit mergeTip, final CodeReviewCommit toMerge) final CodeReviewCommit toMerge)
throws MergeException { throws MergeException {
if (hasMissingDependencies(mergeSorter, toMerge)) { if (hasMissingDependencies(mergeSorter, toMerge)) {
return false; return false;
} }
final ThreeWayMerger m = final ThreeWayMerger m = newThreeWayMerger(repo, createDryRunInserter());
newThreeWayMerger(repo, createDryRunInserter(), useContentMerge);
try { try {
return m.merge(new AnyObjectId[] {mergeTip, toMerge}); return m.merge(new AnyObjectId[] {mergeTip, toMerge});
} catch (NoMergeBaseException e) { } catch (NoMergeBaseException e) {
@@ -379,7 +416,7 @@ public class MergeUtil {
} }
} }
public static boolean canFastForward(final MergeSorter mergeSorter, public boolean canFastForward(final MergeSorter mergeSorter,
final CodeReviewCommit mergeTip, final RevWalk rw, final CodeReviewCommit mergeTip, final RevWalk rw,
final CodeReviewCommit toMerge) throws MergeException { final CodeReviewCommit toMerge) throws MergeException {
if (hasMissingDependencies(mergeSorter, toMerge)) { if (hasMissingDependencies(mergeSorter, toMerge)) {
@@ -393,9 +430,8 @@ public class MergeUtil {
} }
} }
public static boolean canCherryPick(final MergeSorter mergeSorter, public boolean canCherryPick(final MergeSorter mergeSorter,
final Repository repo, final boolean useContentMerge, final Repository repo, final CodeReviewCommit mergeTip, final RevWalk rw,
final CodeReviewCommit mergeTip, final RevWalk rw,
final CodeReviewCommit toMerge) throws MergeException { final CodeReviewCommit toMerge) throws MergeException {
if (mergeTip == null) { if (mergeTip == null) {
// The branch is unborn. Fast-forward is possible. // The branch is unborn. Fast-forward is possible.
@@ -417,7 +453,7 @@ public class MergeUtil {
// //
try { try {
final ThreeWayMerger m = final ThreeWayMerger m =
newThreeWayMerger(repo, createDryRunInserter(), useContentMerge); newThreeWayMerger(repo, createDryRunInserter());
m.setBase(toMerge.getParent(0)); m.setBase(toMerge.getParent(0));
return m.merge(mergeTip, toMerge); return m.merge(mergeTip, toMerge);
} catch (IOException e) { } catch (IOException e) {
@@ -432,10 +468,10 @@ public class MergeUtil {
// instead behave as though MERGE_IF_NECESSARY was configured. // instead behave as though MERGE_IF_NECESSARY was configured.
// //
return canFastForward(mergeSorter, mergeTip, rw, toMerge) return canFastForward(mergeSorter, mergeTip, rw, toMerge)
|| canMerge(mergeSorter, repo, useContentMerge, mergeTip, toMerge); || canMerge(mergeSorter, repo, mergeTip, toMerge);
} }
public static boolean hasMissingDependencies(final MergeSorter mergeSorter, public boolean hasMissingDependencies(final MergeSorter mergeSorter,
final CodeReviewCommit toMerge) throws MergeException { final CodeReviewCommit toMerge) throws MergeException {
try { try {
return !mergeSorter.sort(Collections.singleton(toMerge)).contains(toMerge); return !mergeSorter.sort(Collections.singleton(toMerge)).contains(toMerge);
@@ -444,7 +480,7 @@ public class MergeUtil {
} }
} }
public static ObjectInserter createDryRunInserter() { public ObjectInserter createDryRunInserter() {
return new ObjectInserter() { return new ObjectInserter() {
private final MutableObjectId buf = new MutableObjectId(); private final MutableObjectId buf = new MutableObjectId();
private final static int LAST_BYTE = Constants.OBJECT_ID_LENGTH - 1; private final static int LAST_BYTE = Constants.OBJECT_ID_LENGTH - 1;
@@ -474,18 +510,16 @@ public class MergeUtil {
}; };
} }
public static CodeReviewCommit mergeOneCommit(final ReviewDb reviewDb, public CodeReviewCommit mergeOneCommit(final PersonIdent myIdent,
final IdentifiedUser.GenericFactory identifiedUserFactory, final Repository repo, final RevWalk rw, final ObjectInserter inserter,
final PersonIdent myIdent, final Repository repo, final RevWalk rw, final RevFlag canMergeFlag, final Branch.NameKey destBranch,
final ObjectInserter inserter, final RevFlag canMergeFlag,
final boolean useContentMerge, final Branch.NameKey destBranch,
final CodeReviewCommit mergeTip, final CodeReviewCommit n) final CodeReviewCommit mergeTip, final CodeReviewCommit n)
throws MergeException { throws MergeException {
final ThreeWayMerger m = newThreeWayMerger(repo, inserter, useContentMerge); final ThreeWayMerger m = newThreeWayMerger(repo, inserter);
try { try {
if (m.merge(new AnyObjectId[] {mergeTip, n})) { if (m.merge(new AnyObjectId[] {mergeTip, n})) {
return writeMergeCommit(reviewDb, identifiedUserFactory, myIdent, rw, return writeMergeCommit(myIdent, rw, inserter, canMergeFlag, destBranch,
inserter, canMergeFlag, destBranch, mergeTip, m.getResultTreeId(), n); mergeTip, m.getResultTreeId(), n);
} else { } else {
failed(rw, canMergeFlag, mergeTip, n, CommitMergeStatus.PATH_CONFLICT); failed(rw, canMergeFlag, mergeTip, n, CommitMergeStatus.PATH_CONFLICT);
} }
@@ -528,12 +562,11 @@ public class MergeUtil {
return failed; return failed;
} }
public static CodeReviewCommit writeMergeCommit(final ReviewDb reviewDb, public CodeReviewCommit writeMergeCommit(final PersonIdent myIdent,
final IdentifiedUser.GenericFactory identifiedUserFactory, final RevWalk rw, final ObjectInserter inserter,
final PersonIdent myIdent, final RevWalk rw, final RevFlag canMergeFlag, final Branch.NameKey destBranch,
final ObjectInserter inserter, final RevFlag canMergeFlag, final CodeReviewCommit mergeTip, final ObjectId treeId,
final Branch.NameKey destBranch, final CodeReviewCommit mergeTip, final CodeReviewCommit n) throws IOException,
final ObjectId treeId, final CodeReviewCommit n) throws IOException,
MissingObjectException, IncorrectObjectTypeException { MissingObjectException, IncorrectObjectTypeException {
final List<CodeReviewCommit> merged = new ArrayList<CodeReviewCommit>(); final List<CodeReviewCommit> merged = new ArrayList<CodeReviewCommit>();
rw.resetRetain(canMergeFlag); rw.resetRetain(canMergeFlag);
@@ -579,9 +612,7 @@ public class MergeUtil {
} }
} }
PersonIdent authorIdent = PersonIdent authorIdent = computeMergeCommitAuthor(myIdent, rw, merged);
computeMergeCommitAuthor(reviewDb, identifiedUserFactory, myIdent, rw,
merged);
final CommitBuilder mergeCommit = new CommitBuilder(); final CommitBuilder mergeCommit = new CommitBuilder();
mergeCommit.setTreeId(treeId); mergeCommit.setTreeId(treeId);
@@ -593,8 +624,8 @@ public class MergeUtil {
return (CodeReviewCommit) rw.parseCommit(commit(inserter, mergeCommit)); return (CodeReviewCommit) rw.parseCommit(commit(inserter, mergeCommit));
} }
public static ThreeWayMerger newThreeWayMerger(final Repository repo, public ThreeWayMerger newThreeWayMerger(final Repository repo,
final ObjectInserter inserter, final boolean useContentMerge) { final ObjectInserter inserter) {
ThreeWayMerger m; ThreeWayMerger m;
if (useContentMerge) { if (useContentMerge) {
// Settings for this project allow us to try and // Settings for this project allow us to try and
@@ -623,7 +654,7 @@ public class MergeUtil {
return m; return m;
} }
public static ObjectId commit(final ObjectInserter inserter, public ObjectId commit(final ObjectInserter inserter,
final CommitBuilder mergeCommit) throws IOException, final CommitBuilder mergeCommit) throws IOException,
UnsupportedEncodingException { UnsupportedEncodingException {
ObjectId id = inserter.insert(mergeCommit); ObjectId id = inserter.insert(mergeCommit);
@@ -631,10 +662,9 @@ public class MergeUtil {
return id; return id;
} }
public static PatchSetApproval markCleanMerges(final ReviewDb reviewDb, public PatchSetApproval markCleanMerges(final RevWalk rw,
final RevWalk rw, final RevFlag canMergeFlag, final RevFlag canMergeFlag, final CodeReviewCommit mergeTip,
final CodeReviewCommit mergeTip, final Set<RevCommit> alreadyAccepted) final Set<RevCommit> alreadyAccepted) throws MergeException {
throws MergeException {
if (mergeTip == null) { if (mergeTip == null) {
// If mergeTip is null here, branchTip was null, indicating a new branch // If mergeTip is null here, branchTip was null, indicating a new branch
// at the start of the merge process. We also elected to merge nothing, // at the start of the merge process. We also elected to merge nothing,
@@ -659,7 +689,7 @@ public class MergeUtil {
if (c.patchsetId != null) { if (c.patchsetId != null) {
c.statusCode = CommitMergeStatus.CLEAN_MERGE; c.statusCode = CommitMergeStatus.CLEAN_MERGE;
if (submitApproval == null) { if (submitApproval == null) {
submitApproval = getSubmitter(reviewDb, c.patchsetId); submitApproval = getSubmitter(c.patchsetId);
} }
} }
} }

View File

@@ -14,14 +14,6 @@
package com.google.gerrit.server.git; package com.google.gerrit.server.git;
import static com.google.gerrit.server.git.MergeUtil.canCherryPick;
import static com.google.gerrit.server.git.MergeUtil.canFastForward;
import static com.google.gerrit.server.git.MergeUtil.getApprovalsForCommit;
import static com.google.gerrit.server.git.MergeUtil.getSubmitter;
import static com.google.gerrit.server.git.MergeUtil.hasMissingDependencies;
import static com.google.gerrit.server.git.MergeUtil.markCleanMerges;
import static com.google.gerrit.server.git.MergeUtil.mergeOneCommit;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.gerrit.reviewdb.client.Change; import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet; import com.google.gerrit.reviewdb.client.PatchSet;
@@ -74,7 +66,8 @@ public class RebaseIfNecessary extends SubmitStrategy {
n.statusCode = CommitMergeStatus.CANNOT_REBASE_ROOT; n.statusCode = CommitMergeStatus.CANNOT_REBASE_ROOT;
} else if (n.getParentCount() == 1) { } else if (n.getParentCount() == 1) {
if (canFastForward(args.mergeSorter, newMergeTip, args.rw, n)) { if (args.mergeUtil.canFastForward(
args.mergeSorter, newMergeTip, args.rw, n)) {
newMergeTip = n; newMergeTip = n;
n.statusCode = CommitMergeStatus.CLEAN_MERGE; n.statusCode = CommitMergeStatus.CLEAN_MERGE;
@@ -82,10 +75,11 @@ public class RebaseIfNecessary extends SubmitStrategy {
try { try {
final PatchSet newPatchSet = final PatchSet newPatchSet =
rebaseChange.rebase(args.repo, args.rw, args.inserter, rebaseChange.rebase(args.repo, args.rw, args.inserter,
n.patchsetId, n.change, getSubmitter(args.db, n.patchsetId) n.patchsetId, n.change,
.getAccountId(), newMergeTip, args.useContentMerge); args.mergeUtil.getSubmitter(n.patchsetId).getAccountId(),
newMergeTip, args.mergeUtil);
List<PatchSetApproval> approvals = Lists.newArrayList(); List<PatchSetApproval> approvals = Lists.newArrayList();
for (PatchSetApproval a : getApprovalsForCommit(args.db, n)) { for (PatchSetApproval a : args.mergeUtil.getApprovalsForCommit(n)) {
approvals.add(new PatchSetApproval(newPatchSet.getId(), a)); approvals.add(new PatchSetApproval(newPatchSet.getId(), a));
} }
args.db.patchSetApprovals().insert(approvals); args.db.patchSetApprovals().insert(approvals);
@@ -98,7 +92,7 @@ public class RebaseIfNecessary extends SubmitStrategy {
args.db.changes().get(newPatchSet.getId().getParentKey()); args.db.changes().get(newPatchSet.getId().getParentKey());
newMergeTip.statusCode = CommitMergeStatus.CLEAN_REBASE; newMergeTip.statusCode = CommitMergeStatus.CLEAN_REBASE;
newCommits.put(newPatchSet.getId().getParentKey(), newMergeTip); newCommits.put(newPatchSet.getId().getParentKey(), newMergeTip);
setRefLogIdent(getSubmitter(args.db, n.patchsetId)); setRefLogIdent(args.mergeUtil.getSubmitter(n.patchsetId));
} catch (PathConflictException e) { } catch (PathConflictException e) {
n.statusCode = CommitMergeStatus.PATH_CONFLICT; n.statusCode = CommitMergeStatus.PATH_CONFLICT;
} catch (NoSuchChangeException e) { } catch (NoSuchChangeException e) {
@@ -123,15 +117,12 @@ public class RebaseIfNecessary extends SubmitStrategy {
if (args.rw.isMergedInto(newMergeTip, n)) { if (args.rw.isMergedInto(newMergeTip, n)) {
newMergeTip = n; newMergeTip = n;
} else { } else {
newMergeTip = newMergeTip = args.mergeUtil.mergeOneCommit(
mergeOneCommit(args.db, args.identifiedUserFactory, args.myIdent, args.repo, args.rw, args.inserter,
args.myIdent, args.repo, args.rw, args.inserter, args.canMergeFlag, args.destBranch, newMergeTip, n);
args.canMergeFlag, args.useContentMerge, args.destBranch,
newMergeTip, n);
} }
final PatchSetApproval submitApproval = final PatchSetApproval submitApproval = args.mergeUtil.markCleanMerges(
markCleanMerges(args.db, args.rw, args.canMergeFlag, newMergeTip, args.rw, args.canMergeFlag, newMergeTip, args.alreadyAccepted);
args.alreadyAccepted);
setRefLogIdent(submitApproval); setRefLogIdent(submitApproval);
} catch (IOException e) { } catch (IOException e) {
throw new MergeException("Cannot merge " + n.name(), e); throw new MergeException("Cannot merge " + n.name(), e);
@@ -164,8 +155,8 @@ public class RebaseIfNecessary extends SubmitStrategy {
@Override @Override
public boolean dryRun(final CodeReviewCommit mergeTip, public boolean dryRun(final CodeReviewCommit mergeTip,
final CodeReviewCommit toMerge) throws MergeException { final CodeReviewCommit toMerge) throws MergeException {
return !hasMissingDependencies(args.mergeSorter, toMerge) return !args.mergeUtil.hasMissingDependencies(args.mergeSorter, toMerge)
&& canCherryPick(args.mergeSorter, args.repo, args.useContentMerge, && args.mergeUtil.canCherryPick(args.mergeSorter, args.repo, mergeTip,
mergeTip, args.rw, toMerge); args.rw, toMerge);
} }
} }

View File

@@ -54,14 +54,14 @@ public abstract class SubmitStrategy {
protected final RevFlag canMergeFlag; protected final RevFlag canMergeFlag;
protected final Set<RevCommit> alreadyAccepted; protected final Set<RevCommit> alreadyAccepted;
protected final Branch.NameKey destBranch; protected final Branch.NameKey destBranch;
protected final boolean useContentMerge; protected final MergeUtil mergeUtil;
protected final MergeSorter mergeSorter; protected final MergeSorter mergeSorter;
Arguments(final IdentifiedUser.GenericFactory identifiedUserFactory, Arguments(final IdentifiedUser.GenericFactory identifiedUserFactory,
final PersonIdent myIdent, final ReviewDb db, final Repository repo, final PersonIdent myIdent, final ReviewDb db, final Repository repo,
final RevWalk rw, final ObjectInserter inserter, final RevWalk rw, final ObjectInserter inserter,
final RevFlag canMergeFlag, final Set<RevCommit> alreadyAccepted, final RevFlag canMergeFlag, final Set<RevCommit> alreadyAccepted,
final Branch.NameKey destBranch, final boolean useContentMerge) { final Branch.NameKey destBranch, final MergeUtil mergeUtil) {
this.identifiedUserFactory = identifiedUserFactory; this.identifiedUserFactory = identifiedUserFactory;
this.myIdent = myIdent; this.myIdent = myIdent;
this.db = db; this.db = db;
@@ -72,7 +72,7 @@ public abstract class SubmitStrategy {
this.canMergeFlag = canMergeFlag; this.canMergeFlag = canMergeFlag;
this.alreadyAccepted = alreadyAccepted; this.alreadyAccepted = alreadyAccepted;
this.destBranch = destBranch; this.destBranch = destBranch;
this.useContentMerge = useContentMerge; this.mergeUtil = mergeUtil;
this.mergeSorter = new MergeSorter(rw, alreadyAccepted, canMergeFlag); this.mergeSorter = new MergeSorter(rw, alreadyAccepted, canMergeFlag);
} }
} }

View File

@@ -14,7 +14,6 @@
package com.google.gerrit.server.git; package com.google.gerrit.server.git;
import com.google.gerrit.common.data.LabelTypes;
import com.google.gerrit.reviewdb.client.Branch; import com.google.gerrit.reviewdb.client.Branch;
import com.google.gerrit.reviewdb.client.Project.SubmitType; import com.google.gerrit.reviewdb.client.Project.SubmitType;
import com.google.gerrit.reviewdb.server.ReviewDb; import com.google.gerrit.reviewdb.server.ReviewDb;
@@ -51,10 +50,10 @@ public class SubmitStrategyFactory {
private final IdentifiedUser.GenericFactory identifiedUserFactory; private final IdentifiedUser.GenericFactory identifiedUserFactory;
private final PersonIdent myIdent; private final PersonIdent myIdent;
private final PatchSetInfoFactory patchSetInfoFactory; private final PatchSetInfoFactory patchSetInfoFactory;
private final Provider<String> urlProvider;
private final GitReferenceUpdated gitRefUpdated; private final GitReferenceUpdated gitRefUpdated;
private final RebaseChange rebaseChange; private final RebaseChange rebaseChange;
private final ProjectCache projectCache; private final ProjectCache projectCache;
private final MergeUtil.Factory mergeUtilFactory;
@Inject @Inject
SubmitStrategyFactory( SubmitStrategyFactory(
@@ -63,29 +62,30 @@ public class SubmitStrategyFactory {
final PatchSetInfoFactory patchSetInfoFactory, final PatchSetInfoFactory patchSetInfoFactory,
@CanonicalWebUrl @Nullable final Provider<String> urlProvider, @CanonicalWebUrl @Nullable final Provider<String> urlProvider,
final GitReferenceUpdated gitRefUpdated, final RebaseChange rebaseChange, final GitReferenceUpdated gitRefUpdated, final RebaseChange rebaseChange,
final ProjectCache projectCache) { final ProjectCache projectCache,
final MergeUtil.Factory mergeUtilFactory) {
this.identifiedUserFactory = identifiedUserFactory; this.identifiedUserFactory = identifiedUserFactory;
this.myIdent = myIdent; this.myIdent = myIdent;
this.patchSetInfoFactory = patchSetInfoFactory; this.patchSetInfoFactory = patchSetInfoFactory;
this.urlProvider = urlProvider;
this.gitRefUpdated = gitRefUpdated; this.gitRefUpdated = gitRefUpdated;
this.rebaseChange = rebaseChange; this.rebaseChange = rebaseChange;
this.projectCache = projectCache; this.projectCache = projectCache;
this.mergeUtilFactory = mergeUtilFactory;
} }
public SubmitStrategy create(final SubmitType submitType, final ReviewDb db, public SubmitStrategy create(final SubmitType submitType, final ReviewDb db,
final Repository repo, final RevWalk rw, final ObjectInserter inserter, final Repository repo, final RevWalk rw, final ObjectInserter inserter,
final RevFlag canMergeFlag, final Set<RevCommit> alreadyAccepted, final RevFlag canMergeFlag, final Set<RevCommit> alreadyAccepted,
final Branch.NameKey destBranch, final boolean useContentMerge) final Branch.NameKey destBranch)
throws MergeException, NoSuchProjectException { throws MergeException, NoSuchProjectException {
ProjectState project = getProject(destBranch);
final SubmitStrategy.Arguments args = final SubmitStrategy.Arguments args =
new SubmitStrategy.Arguments(identifiedUserFactory, myIdent, db, repo, new SubmitStrategy.Arguments(identifiedUserFactory, myIdent, db, repo,
rw, inserter, canMergeFlag, alreadyAccepted, destBranch, rw, inserter, canMergeFlag, alreadyAccepted, destBranch,
useContentMerge); mergeUtilFactory.create(project));
switch (submitType) { switch (submitType) {
case CHERRY_PICK: case CHERRY_PICK:
return new CherryPick(args, patchSetInfoFactory, urlProvider, return new CherryPick(args, patchSetInfoFactory, gitRefUpdated);
getLabelTypes(destBranch), gitRefUpdated);
case FAST_FORWARD_ONLY: case FAST_FORWARD_ONLY:
return new FastForwardOnly(args); return new FastForwardOnly(args);
case MERGE_ALWAYS: case MERGE_ALWAYS:
@@ -101,12 +101,12 @@ public class SubmitStrategyFactory {
} }
} }
private LabelTypes getLabelTypes(Branch.NameKey branch) private ProjectState getProject(Branch.NameKey branch)
throws NoSuchProjectException { throws NoSuchProjectException {
final ProjectState p = projectCache.get(branch.getParentKey()); final ProjectState p = projectCache.get(branch.getParentKey());
if (p == null) { if (p == null) {
throw new NoSuchProjectException(branch.getParentKey()); throw new NoSuchProjectException(branch.getParentKey());
} }
return p.getLabelTypes(); return p;
} }
} }