CherryPick: Keep going in the face of a single merge conflict

In addition to verifying this behavior in a test, this also fixes an
issue caused by setting mergeTip to null. On the next iteration of the
loop we were incorrectly treating the null merge tip as a cherry-pick
onto an unborn root. Setting the commit as CLEAN_MERGE resulted in
rejecting the later ref update in MergeOp.

Change-Id: I82299ea96725a21430a0871199cde3e2f3af267b
This commit is contained in:
Dave Borowitz
2015-02-18 07:39:47 -08:00
parent c0af7dbeca
commit 8cbf929a20
2 changed files with 43 additions and 12 deletions

View File

@@ -72,11 +72,11 @@ public class CherryPick extends SubmitStrategy {
CodeReviewCommit n = sorted.remove(0);
try {
if (mergeTip.getCurrentTip() == null) {
mergeTip = cherryPickUnbornRoot(n);
cherryPickUnbornRoot(n, mergeTip);
} else if (n.getParentCount() == 0) {
cherryPickRootOntoBranch(n);
} else if (n.getParentCount() == 1) {
mergeTip = cherryPickOne(n, mergeTip);
cherryPickOne(n, mergeTip);
} else {
cherryPickMultipleParents(n, mergeTip);
}
@@ -87,11 +87,10 @@ public class CherryPick extends SubmitStrategy {
return mergeTip;
}
private MergeTip cherryPickUnbornRoot(CodeReviewCommit n) {
private void cherryPickUnbornRoot(CodeReviewCommit n, MergeTip mergeTip) {
// The branch is unborn. Take fast-forward resolution to create the branch.
MergeTip mergeTip = new MergeTip(n, Lists.newArrayList(n));
mergeTip.moveTipTo(n, n);
n.setStatusCode(CommitMergeStatus.CLEAN_MERGE);
return mergeTip;
}
private void cherryPickRootOntoBranch(CodeReviewCommit n) {
@@ -100,24 +99,24 @@ public class CherryPick extends SubmitStrategy {
n.setStatusCode(CommitMergeStatus.CANNOT_CHERRY_PICK_ROOT);
}
private MergeTip cherryPickOne(CodeReviewCommit n, MergeTip mergeTip)
private void cherryPickOne(CodeReviewCommit n, MergeTip mergeTip)
throws NoSuchChangeException, OrmException, IOException {
// If there is only one parent, a cherry-pick can be done by
// taking the delta relative to that one parent and redoing
// that on the current merge tip.
// If there is only one parent, a cherry-pick can be done by taking the
// delta relative to that one parent and redoing that on the current merge
// tip.
//
// Keep going in the case of a single merge failure; the goal is to
// cherry-pick as many commits as possible.
try {
CodeReviewCommit merge =
writeCherryPickCommit(mergeTip.getCurrentTip(), n);
mergeTip.moveTipTo(merge, merge);
newCommits.put(mergeTip.getCurrentTip().getPatchsetId()
.getParentKey(), mergeTip.getCurrentTip());
return mergeTip;
} catch (MergeConflictException mce) {
n.setStatusCode(CommitMergeStatus.PATH_CONFLICT);
return null;
} catch (MergeIdenticalTreeException mie) {
n.setStatusCode(CommitMergeStatus.ALREADY_MERGED);
return null;
}
}