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:
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user