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 ChangeHookRunner hooks;
private final ApprovalsUtil approvalsUtil;
private final MergeUtil.Factory mergeUtilFactory;
@Inject
RebaseChange(final ChangeControl.Factory changeControlFactory,
@@ -81,7 +82,8 @@ public class RebaseChange {
final GitRepositoryManager gitManager,
final GitReferenceUpdated gitRefUpdated,
final RebasedPatchSetSender.Factory rebasedPatchSetSenderFactory,
final ChangeHookRunner hooks, final ApprovalsUtil approvalsUtil) {
final ChangeHookRunner hooks, final ApprovalsUtil approvalsUtil,
final MergeUtil.Factory mergeUtilFactory) {
this.changeControlFactory = changeControlFactory;
this.patchSetInfoFactory = patchSetInfoFactory;
this.db = db;
@@ -91,6 +93,7 @@ public class RebaseChange {
this.rebasedPatchSetSenderFactory = rebasedPatchSetSenderFactory;
this.hooks = hooks;
this.approvalsUtil = approvalsUtil;
this.mergeUtilFactory = mergeUtilFactory;
}
/**
@@ -149,7 +152,8 @@ public class RebaseChange {
final PatchSet newPatchSet =
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> oldCC = Sets.newHashSet();
@@ -290,7 +294,7 @@ public class RebaseChange {
* @param chg the change that should be rebased
* @param uploader the user that creates the rebased patch set
* @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
* @throws NoSuchChangeException thrown if the change to which the patch set
* 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,
final ObjectInserter inserter, final PatchSet.Id patchSetId,
final Change chg, final Account.Id uploader, final RevCommit baseCommit,
final boolean useContentMerge) throws NoSuchChangeException,
final MergeUtil mergeUtil) throws NoSuchChangeException,
OrmException, IOException, InvalidChangeOperationException,
PathConflictException {
Change change = chg;
@@ -309,9 +313,8 @@ public class RebaseChange {
final RevCommit rebasedCommit;
ObjectId oldId = ObjectId.fromString(originalPatchSet.getRevision().get());
ObjectId newId =
rebaseCommit(git, inserter, revWalk.parseCommit(oldId), baseCommit,
useContentMerge, myIdent);
ObjectId newId = rebaseCommit(git, inserter, revWalk.parseCommit(oldId),
baseCommit, mergeUtil, myIdent);
rebasedCommit = revWalk.parseCommit(newId);
@@ -400,15 +403,15 @@ public class RebaseChange {
* @param inserter inserter to handle new trees and blobs
* @param original The commit to rebase
* @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
* @return the id of the rebased commit
* @throws IOException Merged failed
* @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 RevCommit base, final boolean useContentMerge,
final RevCommit base, final MergeUtil mergeUtil,
final PersonIdent committerIdent) throws IOException,
PathConflictException {
@@ -418,7 +421,7 @@ public class RebaseChange {
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.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.GitModule;
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.ReloadSubmitQueueOp;
import com.google.gerrit.server.git.TagCache;
@@ -180,6 +181,7 @@ public class GerritGlobalModule extends FactoryModule {
factory(InternalUser.Factory.class);
factory(MergedSender.Factory.class);
factory(MergeFailSender.Factory.class);
factory(MergeUtil.Factory.class);
factory(PerformCreateGroup.Factory.class);
factory(PerformRenameGroup.Factory.class);
factory(ProjectNode.Factory.class);

View File

@@ -14,17 +14,7 @@
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.gerrit.common.data.LabelTypes;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
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.patch.PatchSetInfoFactory;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Provider;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.PersonIdent;
@@ -52,20 +41,15 @@ import java.util.Map;
public class CherryPick extends SubmitStrategy {
private final PatchSetInfoFactory patchSetInfoFactory;
private final Provider<String> urlProvider;
private final LabelTypes labelTypes;
private final GitReferenceUpdated gitRefUpdated;
private final Map<Change.Id, CodeReviewCommit> newCommits;
CherryPick(final SubmitStrategy.Arguments args,
final PatchSetInfoFactory patchSetInfoFactory,
final Provider<String> urlProvider, final LabelTypes labelTypes,
final GitReferenceUpdated gitRefUpdated) {
super(args);
this.patchSetInfoFactory = patchSetInfoFactory;
this.urlProvider = urlProvider;
this.labelTypes = labelTypes;
this.gitRefUpdated = gitRefUpdated;
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
// 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)) {
newMergeTip = n;
} else {
newMergeTip =
mergeOneCommit(args.db, args.identifiedUserFactory,
args.myIdent, args.repo, args.rw, args.inserter,
args.canMergeFlag, args.useContentMerge, args.destBranch,
newMergeTip, n);
args.mergeUtil.mergeOneCommit(args.myIdent, args.repo,
args.rw, args.inserter, args.canMergeFlag,
args.destBranch, newMergeTip, n);
}
final PatchSetApproval submitApproval =
markCleanMerges(args.db, args.rw, args.canMergeFlag,
args.mergeUtil.markCleanMerges(args.rw, args.canMergeFlag,
newMergeTip, args.alreadyAccepted);
setRefLogIdent(submitApproval);
@@ -150,7 +133,7 @@ public class CherryPick extends SubmitStrategy {
args.rw.parseBody(n);
final PatchSetApproval submitAudit =
getSubmitter(args.db, n.change.currentPatchSetId());
args.mergeUtil.getSubmitter(n.change.currentPatchSetId());
PersonIdent cherryPickCommitterIdent = null;
if (submitAudit != null) {
@@ -162,13 +145,11 @@ public class CherryPick extends SubmitStrategy {
cherryPickCommitterIdent = args.myIdent;
}
final String cherryPickCmtMsg =
createCherryPickCommitMessage(n, labelTypes, urlProvider, args.db,
args.identifiedUserFactory);
final String cherryPickCmtMsg = args.mergeUtil.createCherryPickCommitMessage(n);
final CodeReviewCommit newCommit =
createCherryPickFromCommit(args.repo, args.inserter, mergeTip, n,
cherryPickCommitterIdent, cherryPickCmtMsg, args.rw, args.useContentMerge);
args.mergeUtil.createCherryPickFromCommit(args.repo, args.inserter, mergeTip, n,
cherryPickCommitterIdent, cherryPickCmtMsg, args.rw);
if (newCommit == null) {
return null;
@@ -187,7 +168,7 @@ public class CherryPick extends SubmitStrategy {
args.db.changes().update(Collections.singletonList(n.change));
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));
}
args.db.patchSetApprovals().insert(approvals);
@@ -233,7 +214,7 @@ public class CherryPick extends SubmitStrategy {
@Override
public boolean dryRun(final CodeReviewCommit mergeTip,
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);
}
}

View File

@@ -14,11 +14,6 @@
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 java.util.List;
@@ -32,9 +27,9 @@ public class FastForwardOnly extends SubmitStrategy {
@Override
protected CodeReviewCommit _run(final CodeReviewCommit mergeTip,
final List<CodeReviewCommit> toMerge) throws MergeException {
reduceToMinimalMerge(args.mergeSorter, toMerge);
args.mergeUtil.reduceToMinimalMerge(args.mergeSorter, toMerge);
final CodeReviewCommit newMergeTip =
getFirstFastForward(mergeTip, args.rw, toMerge);
args.mergeUtil.getFirstFastForward(mergeTip, args.rw, toMerge);
while (!toMerge.isEmpty()) {
final CodeReviewCommit n = toMerge.remove(0);
@@ -42,7 +37,7 @@ public class FastForwardOnly extends SubmitStrategy {
}
final PatchSetApproval submitApproval =
markCleanMerges(args.db, args.rw, args.canMergeFlag, newMergeTip,
args.mergeUtil.markCleanMerges(args.rw, args.canMergeFlag, newMergeTip,
args.alreadyAccepted);
setRefLogIdent(submitApproval);
@@ -56,6 +51,7 @@ public class FastForwardOnly extends SubmitStrategy {
public boolean dryRun(final CodeReviewCommit mergeTip,
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;
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 java.util.List;
@@ -32,19 +27,18 @@ public class MergeAlways extends SubmitStrategy {
@Override
protected CodeReviewCommit _run(final CodeReviewCommit mergeTip,
final List<CodeReviewCommit> toMerge) throws MergeException {
reduceToMinimalMerge(args.mergeSorter, toMerge);
args.mergeUtil.reduceToMinimalMerge(args.mergeSorter, toMerge);
CodeReviewCommit newMergeTip = mergeTip;
while (!toMerge.isEmpty()) {
newMergeTip =
mergeOneCommit(args.db, args.identifiedUserFactory, args.myIdent,
args.repo, args.rw, args.inserter, args.canMergeFlag,
args.useContentMerge, args.destBranch, mergeTip,
args.mergeUtil.mergeOneCommit(args.myIdent, args.repo, args.rw,
args.inserter, args.canMergeFlag, args.destBranch, mergeTip,
toMerge.remove(0));
}
final PatchSetApproval submitApproval =
markCleanMerges(args.db, args.rw, args.canMergeFlag, newMergeTip,
args.mergeUtil.markCleanMerges(args.rw, args.canMergeFlag, newMergeTip,
args.alreadyAccepted);
setRefLogIdent(submitApproval);
@@ -54,7 +48,7 @@ public class MergeAlways extends SubmitStrategy {
@Override
public boolean dryRun(final CodeReviewCommit mergeTip,
final CodeReviewCommit toMerge) throws MergeException {
return canMerge(args.mergeSorter, args.repo, args.useContentMerge,
mergeTip, toMerge);
return args.mergeUtil.canMerge(args.mergeSorter, args.repo, mergeTip,
toMerge);
}
}

View File

@@ -14,13 +14,6 @@
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 java.util.List;
@@ -34,22 +27,20 @@ public class MergeIfNecessary extends SubmitStrategy {
@Override
protected CodeReviewCommit _run(final CodeReviewCommit mergeTip,
final List<CodeReviewCommit> toMerge) throws MergeException {
reduceToMinimalMerge(args.mergeSorter, toMerge);
args.mergeUtil.reduceToMinimalMerge(args.mergeSorter, toMerge);
CodeReviewCommit newMergeTip =
getFirstFastForward(mergeTip, args.rw, toMerge);
args.mergeUtil.getFirstFastForward(mergeTip, args.rw, toMerge);
// For every other commit do a pair-wise merge.
while (!toMerge.isEmpty()) {
newMergeTip =
mergeOneCommit(args.db, args.identifiedUserFactory, args.myIdent,
args.repo, args.rw, args.inserter, args.canMergeFlag,
args.useContentMerge, args.destBranch, mergeTip,
args.mergeUtil.mergeOneCommit(args.myIdent, args.repo, args.rw,
args.inserter, args.canMergeFlag, args.destBranch, mergeTip,
toMerge.remove(0));
}
final PatchSetApproval submitApproval =
markCleanMerges(args.db, args.rw, args.canMergeFlag, newMergeTip,
args.alreadyAccepted);
final PatchSetApproval submitApproval = args.mergeUtil.markCleanMerges(
args.rw, args.canMergeFlag, newMergeTip, args.alreadyAccepted);
setRefLogIdent(submitApproval);
return newMergeTip;
@@ -58,8 +49,9 @@ public class MergeIfNecessary extends SubmitStrategy {
@Override
public boolean dryRun(final CodeReviewCommit mergeTip,
final CodeReviewCommit toMerge) throws MergeException {
return canFastForward(args.mergeSorter, mergeTip, args.rw, toMerge)
|| canMerge(args.mergeSorter, args.repo, args.useContentMerge,
mergeTip, toMerge);
return args.mergeUtil.canFastForward(
args.mergeSorter, mergeTip, args.rw, 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)
throws MergeException, NoSuchProjectException {
return submitStrategyFactory.create(submitType, db, repo, rw, inserter,
canMergeFlag, getAlreadyAccepted(branchTip), destBranch,
destProject.isUseContentMerge());
canMergeFlag, getAlreadyAccepted(branchTip), destBranch);
}
private void openRepository() throws MergeException {

View File

@@ -15,7 +15,6 @@
package com.google.gerrit.server.git;
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.ApprovalCategory;
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.server.ReviewDb;
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.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.MissingObjectException;
@@ -64,9 +67,16 @@ import java.util.List;
import java.util.Set;
import java.util.TimeZone;
import javax.annotation.Nullable;
public class MergeUtil {
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 =
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 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 List<CodeReviewCommit> toMerge) throws MergeException {
for (final Iterator<CodeReviewCommit> i = toMerge.iterator(); i.hasNext();) {
@@ -95,7 +133,7 @@ public class MergeUtil {
return mergeTip;
}
public static void reduceToMinimalMerge(final MergeSorter mergeSorter,
public void reduceToMinimalMerge(final MergeSorter mergeSorter,
final List<CodeReviewCommit> toSort) throws MergeException {
final Collection<CodeReviewCommit> heads;
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,
final PatchSet.Id c) {
if (c == null) {
@@ -137,13 +179,12 @@ public class MergeUtil {
return submitter;
}
public static CodeReviewCommit createCherryPickFromCommit(Repository repo,
public CodeReviewCommit createCherryPickFromCommit(Repository repo,
ObjectInserter inserter, CodeReviewCommit mergeTip, CodeReviewCommit originalCommit,
PersonIdent cherryPickCommitterIdent, String commitMsg, RevWalk rw,
Boolean useContentMerge) throws MissingObjectException, IncorrectObjectTypeException, IOException {
PersonIdent cherryPickCommitterIdent, String commitMsg, RevWalk rw)
throws MissingObjectException, IncorrectObjectTypeException, IOException {
final ThreeWayMerger m =
newThreeWayMerger(repo, inserter, useContentMerge);
final ThreeWayMerger m = newThreeWayMerger(repo, inserter);
m.setBase(originalCommit.getParent(0));
if (m.merge(mergeTip, originalCommit)) {
@@ -166,9 +207,7 @@ public class MergeUtil {
}
}
public static String createCherryPickCommitMessage(final CodeReviewCommit n,
final LabelTypes labelTypes, final Provider<String> urlProvider,
final ReviewDb db, final IdentifiedUser.GenericFactory identifiedUserFactory) {
public String createCherryPickCommitMessage(final CodeReviewCommit n) {
final List<FooterLine> footers = n.getFooterLines();
final StringBuilder msgbuf = new StringBuilder();
msgbuf.append(n.getFullMessage());
@@ -208,7 +247,7 @@ public class MergeUtil {
PatchSetApproval submitAudit = null;
for (final PatchSetApproval a : getApprovalsForCommit(db, n)) {
for (final PatchSetApproval a : getApprovalsForCommit(n)) {
if (a.getValue() <= 0) {
// Negative votes aren't counted.
continue;
@@ -256,7 +295,8 @@ public class MergeUtil {
} else if (VRIF.equals(a.getCategoryId())) {
tag = "Tested-by";
} else {
final LabelType lt = labelTypes.byId(a.getCategoryId().get());
final LabelType lt =
project.getLabelTypes().byId(a.getCategoryId().get());
if (lt == null) {
// TODO: Support arbitrary labels.
continue;
@@ -275,10 +315,10 @@ public class MergeUtil {
return msgbuf.toString();
}
public static List<PatchSetApproval> getApprovalsForCommit(final ReviewDb db, final CodeReviewCommit n) {
public List<PatchSetApproval> getApprovalsForCommit(final CodeReviewCommit n) {
try {
List<PatchSetApproval> approvalList =
db.patchSetApprovals().byPatchSet(n.patchsetId).toList();
db.get().patchSetApprovals().byPatchSet(n.patchsetId).toList();
Collections.sort(approvalList, new Comparator<PatchSetApproval>() {
@Override
public int compare(final PatchSetApproval a, final PatchSetApproval b) {
@@ -311,13 +351,11 @@ public class MergeUtil {
return false;
}
public static PersonIdent computeMergeCommitAuthor(final ReviewDb reviewDb,
final IdentifiedUser.GenericFactory identifiedUserFactory,
final PersonIdent myIdent, final RevWalk rw,
final List<CodeReviewCommit> codeReviewCommits) {
public PersonIdent computeMergeCommitAuthor(final PersonIdent myIdent,
final RevWalk rw, final List<CodeReviewCommit> codeReviewCommits) {
PatchSetApproval submitter = null;
for (final CodeReviewCommit c : codeReviewCommits) {
PatchSetApproval s = getSubmitter(reviewDb, c.patchsetId);
PatchSetApproval s = getSubmitter(c.patchsetId);
if (submitter == null
|| (s != null && s.getGranted().compareTo(submitter.getGranted()) > 0)) {
submitter = s;
@@ -360,16 +398,15 @@ public class MergeUtil {
return authorIdent;
}
public static boolean canMerge(final MergeSorter mergeSorter,
final Repository repo, final boolean useContentMerge,
final CodeReviewCommit mergeTip, final CodeReviewCommit toMerge)
public boolean canMerge(final MergeSorter mergeSorter,
final Repository repo, final CodeReviewCommit mergeTip,
final CodeReviewCommit toMerge)
throws MergeException {
if (hasMissingDependencies(mergeSorter, toMerge)) {
return false;
}
final ThreeWayMerger m =
newThreeWayMerger(repo, createDryRunInserter(), useContentMerge);
final ThreeWayMerger m = newThreeWayMerger(repo, createDryRunInserter());
try {
return m.merge(new AnyObjectId[] {mergeTip, toMerge});
} 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 toMerge) throws MergeException {
if (hasMissingDependencies(mergeSorter, toMerge)) {
@@ -393,9 +430,8 @@ public class MergeUtil {
}
}
public static boolean canCherryPick(final MergeSorter mergeSorter,
final Repository repo, final boolean useContentMerge,
final CodeReviewCommit mergeTip, final RevWalk rw,
public boolean canCherryPick(final MergeSorter mergeSorter,
final Repository repo, final CodeReviewCommit mergeTip, final RevWalk rw,
final CodeReviewCommit toMerge) throws MergeException {
if (mergeTip == null) {
// The branch is unborn. Fast-forward is possible.
@@ -417,7 +453,7 @@ public class MergeUtil {
//
try {
final ThreeWayMerger m =
newThreeWayMerger(repo, createDryRunInserter(), useContentMerge);
newThreeWayMerger(repo, createDryRunInserter());
m.setBase(toMerge.getParent(0));
return m.merge(mergeTip, toMerge);
} catch (IOException e) {
@@ -432,10 +468,10 @@ public class MergeUtil {
// instead behave as though MERGE_IF_NECESSARY was configured.
//
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 {
try {
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() {
private final MutableObjectId buf = new MutableObjectId();
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,
final IdentifiedUser.GenericFactory identifiedUserFactory,
final PersonIdent myIdent, final Repository repo, final RevWalk rw,
final ObjectInserter inserter, final RevFlag canMergeFlag,
final boolean useContentMerge, final Branch.NameKey destBranch,
public CodeReviewCommit mergeOneCommit(final PersonIdent myIdent,
final Repository repo, final RevWalk rw, final ObjectInserter inserter,
final RevFlag canMergeFlag, final Branch.NameKey destBranch,
final CodeReviewCommit mergeTip, final CodeReviewCommit n)
throws MergeException {
final ThreeWayMerger m = newThreeWayMerger(repo, inserter, useContentMerge);
final ThreeWayMerger m = newThreeWayMerger(repo, inserter);
try {
if (m.merge(new AnyObjectId[] {mergeTip, n})) {
return writeMergeCommit(reviewDb, identifiedUserFactory, myIdent, rw,
inserter, canMergeFlag, destBranch, mergeTip, m.getResultTreeId(), n);
return writeMergeCommit(myIdent, rw, inserter, canMergeFlag, destBranch,
mergeTip, m.getResultTreeId(), n);
} else {
failed(rw, canMergeFlag, mergeTip, n, CommitMergeStatus.PATH_CONFLICT);
}
@@ -528,12 +562,11 @@ public class MergeUtil {
return failed;
}
public static CodeReviewCommit writeMergeCommit(final ReviewDb reviewDb,
final IdentifiedUser.GenericFactory identifiedUserFactory,
final PersonIdent myIdent, final RevWalk rw,
final ObjectInserter inserter, final RevFlag canMergeFlag,
final Branch.NameKey destBranch, final CodeReviewCommit mergeTip,
final ObjectId treeId, final CodeReviewCommit n) throws IOException,
public CodeReviewCommit writeMergeCommit(final PersonIdent myIdent,
final RevWalk rw, final ObjectInserter inserter,
final RevFlag canMergeFlag, final Branch.NameKey destBranch,
final CodeReviewCommit mergeTip, final ObjectId treeId,
final CodeReviewCommit n) throws IOException,
MissingObjectException, IncorrectObjectTypeException {
final List<CodeReviewCommit> merged = new ArrayList<CodeReviewCommit>();
rw.resetRetain(canMergeFlag);
@@ -579,9 +612,7 @@ public class MergeUtil {
}
}
PersonIdent authorIdent =
computeMergeCommitAuthor(reviewDb, identifiedUserFactory, myIdent, rw,
merged);
PersonIdent authorIdent = computeMergeCommitAuthor(myIdent, rw, merged);
final CommitBuilder mergeCommit = new CommitBuilder();
mergeCommit.setTreeId(treeId);
@@ -593,8 +624,8 @@ public class MergeUtil {
return (CodeReviewCommit) rw.parseCommit(commit(inserter, mergeCommit));
}
public static ThreeWayMerger newThreeWayMerger(final Repository repo,
final ObjectInserter inserter, final boolean useContentMerge) {
public ThreeWayMerger newThreeWayMerger(final Repository repo,
final ObjectInserter inserter) {
ThreeWayMerger m;
if (useContentMerge) {
// Settings for this project allow us to try and
@@ -623,7 +654,7 @@ public class MergeUtil {
return m;
}
public static ObjectId commit(final ObjectInserter inserter,
public ObjectId commit(final ObjectInserter inserter,
final CommitBuilder mergeCommit) throws IOException,
UnsupportedEncodingException {
ObjectId id = inserter.insert(mergeCommit);
@@ -631,10 +662,9 @@ public class MergeUtil {
return id;
}
public static PatchSetApproval markCleanMerges(final ReviewDb reviewDb,
final RevWalk rw, final RevFlag canMergeFlag,
final CodeReviewCommit mergeTip, final Set<RevCommit> alreadyAccepted)
throws MergeException {
public PatchSetApproval markCleanMerges(final RevWalk rw,
final RevFlag canMergeFlag, final CodeReviewCommit mergeTip,
final Set<RevCommit> alreadyAccepted) throws MergeException {
if (mergeTip == null) {
// 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,
@@ -659,7 +689,7 @@ public class MergeUtil {
if (c.patchsetId != null) {
c.statusCode = CommitMergeStatus.CLEAN_MERGE;
if (submitApproval == null) {
submitApproval = getSubmitter(reviewDb, c.patchsetId);
submitApproval = getSubmitter(c.patchsetId);
}
}
}

View File

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

View File

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

View File

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