diff --git a/mgrapp/src/com/google/codereview/manager/merge/CodeReviewCommit.java b/mgrapp/src/com/google/codereview/manager/merge/CodeReviewCommit.java index 7d64ebb0e9..8542240cc9 100644 --- a/mgrapp/src/com/google/codereview/manager/merge/CodeReviewCommit.java +++ b/mgrapp/src/com/google/codereview/manager/merge/CodeReviewCommit.java @@ -19,6 +19,8 @@ import com.google.codereview.internal.PostMergeResult.MergeResultItem; import org.spearce.jgit.lib.AnyObjectId; import org.spearce.jgit.revwalk.RevCommit; +import java.util.List; + /** Extended commit entity with code review specific metadata. */ class CodeReviewCommit extends RevCommit { /** @@ -45,6 +47,9 @@ class CodeReviewCommit extends RevCommit { */ MergeResultItem.CodeType statusCode; + /** Commits which are missing ancestors of this commit. */ + List missing; + CodeReviewCommit(final AnyObjectId id) { super(id); } diff --git a/mgrapp/src/com/google/codereview/manager/merge/MergeOp.java b/mgrapp/src/com/google/codereview/manager/merge/MergeOp.java index aabd3e55fa..5e9bf81327 100644 --- a/mgrapp/src/com/google/codereview/manager/merge/MergeOp.java +++ b/mgrapp/src/com/google/codereview/manager/merge/MergeOp.java @@ -17,6 +17,7 @@ package com.google.codereview.manager.merge; import com.google.codereview.internal.PendingMerge.PendingMergeItem; import com.google.codereview.internal.PendingMerge.PendingMergeResponse; import com.google.codereview.internal.PostMergeResult.MergeResultItem; +import com.google.codereview.internal.PostMergeResult.MissingDependencyItem; import com.google.codereview.internal.PostMergeResult.PostMergeResultRequest; import com.google.codereview.manager.Backend; import com.google.codereview.manager.InvalidRepositoryException; @@ -381,6 +382,21 @@ class MergeOp { final MergeResultItem.Builder delay = MergeResultItem.newBuilder(); delay.setStatusCode(c.statusCode); delay.setPatchsetKey(c.patchsetKey); + + if (c.statusCode == MergeResultItem.CodeType.MISSING_DEPENDENCY) { + for (final CodeReviewCommit m : c.missing) { + final MissingDependencyItem.Builder d; + + d = MissingDependencyItem.newBuilder(); + if (m.patchsetKey != null) { + d.setPatchsetKey(m.patchsetKey); + } else { + d.setRevisionId(m.getId().name()); + } + delay.addMissing(d); + } + } + return delay.build(); } } diff --git a/mgrapp/src/com/google/codereview/manager/merge/MergeSorter.java b/mgrapp/src/com/google/codereview/manager/merge/MergeSorter.java index 0fa45baa13..39d1ce2cdd 100644 --- a/mgrapp/src/com/google/codereview/manager/merge/MergeSorter.java +++ b/mgrapp/src/com/google/codereview/manager/merge/MergeSorter.java @@ -22,6 +22,7 @@ import org.spearce.jgit.revwalk.RevFlag; import org.spearce.jgit.revwalk.RevWalk; import java.io.IOException; +import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; @@ -42,7 +43,7 @@ class MergeSorter { throws IOException { final Set heads = new HashSet(); final Set sort = prepareList(incoming); - INCOMING: while (!sort.isEmpty()) { + while (!sort.isEmpty()) { final CodeReviewCommit n = removeOne(sort); rw.resetRetain(CAN_MERGE); @@ -58,10 +59,18 @@ class MergeSorter { // We cannot merge n as it would bring something we // aren't permitted to merge at this time. Drop n. // - n.statusCode = MergeResultItem.CodeType.MISSING_DEPENDENCY; - continue INCOMING; + if (n.missing == null) { + n.statusCode = MergeResultItem.CodeType.MISSING_DEPENDENCY; + n.missing = new ArrayList(); + } + n.missing.add((CodeReviewCommit) c); + } else { + contents.add(c); } - contents.add(c); + } + + if (n.statusCode == MergeResultItem.CodeType.MISSING_DEPENDENCY) { + continue; } // Anything reachable through us is better merged by just diff --git a/proto/internal/post_merge_result.proto b/proto/internal/post_merge_result.proto index cea637121d..ebcc9e5a7e 100644 --- a/proto/internal/post_merge_result.proto +++ b/proto/internal/post_merge_result.proto @@ -15,6 +15,18 @@ package codereview.internal; option java_package = "com.google.codereview.internal"; +message MissingDependencyItem { + // Unique key of the PatchSet that is missing; missing + // if the patchset is not known but the revision is. + // + optional string patchset_key = 1; + + // Unique revision id of the revision that is missing, + // if patchset_key was not available to the processor. + // + optional string revision_id = 2; +} + message MergeResultItem { enum CodeType { CLEAN_MERGE = 1; // change merged clean @@ -27,6 +39,11 @@ message MergeResultItem { // Unique key of the PatchSet to merge // required string patchset_key = 2; + + // If status_code = MISSING_DEPENDENCY this is the list of + // ancestors needed to merge this item into the branch. + // + repeated MissingDependencyItem missing = 3; } message PostMergeResultRequest {