Fix partial merge of cross-repo
Change-Id: Id95b0e33ad6036d006015f9658485e8e2aed911b
diff --git a/src/main/java/com/criteo/gerrit/plugins/automerge/AutomaticMerger.java b/src/main/java/com/criteo/gerrit/plugins/automerge/AutomaticMerger.java
index 4696b2d..04cf63d 100644
--- a/src/main/java/com/criteo/gerrit/plugins/automerge/AutomaticMerger.java
+++ b/src/main/java/com/criteo/gerrit/plugins/automerge/AutomaticMerger.java
@@ -160,8 +160,7 @@
if (atomicityHelper.isAtomicReview(change)) {
attemptToMergeAtomic(change);
} else {
- log.info("Submitting non-atomic change {}...", change.number);
- atomicityHelper.mergeReview(change.project, change.number);
+ attemptToMergeNonAtomic(change);
}
}
}
@@ -225,6 +224,24 @@
}
}
+ private void attemptToMergeNonAtomic(Change change)
+ throws IOException, OrmException, RestApiException {
+ // There may be a parent commit that it not merged while having all approvals
+ // because it is part of a cross-repo. We take care to not let Gerrit merge it
+ // by merging only the commits whose parents are already merged.
+ boolean dependsOnNonMergedCommit =
+ atomicityHelper.hasDependentReview(change.project, change.number);
+ if (dependsOnNonMergedCommit) {
+ log.info(
+ "Change {} is not mergeable because it depends on a non merged commit.",
+ change.number);
+ return;
+ }
+
+ log.info("Submitting non-atomic change {}...", change.number);
+ atomicityHelper.mergeReview(change.project, change.number);
+ }
+
private void processNewAtomicPatchSet(Change change) {
try {
checkReviewExists(change.number);
diff --git a/test.rb b/test.rb
index e6b932d..995cbb9 100755
--- a/test.rb
+++ b/test.rb
@@ -107,6 +107,20 @@
check_status(commit2, 'MERGED')
end
+ def test_commit_above_non_mergeable_crossrepo
+ commit1a = create_review(PROJECT1, "review1a on #{PROJECT1}", "crossrepo/topic1")
+ commit1b = create_review(PROJECT1, "review1b on #{PROJECT1}")
+ commit2 = create_review(PROJECT2, "review2 on #{PROJECT2}", "crossrepo/topic1")
+ approve_review(commit1a)
+ check_status(commit1a, 'NEW')
+ check_status(commit1b, 'NEW')
+ check_status(commit2, 'NEW')
+
+ approve_review(commit1b)
+
+ check_status(commit1b, 'NEW')
+ end
+
def test_refupdatedevent_merge_upper_commit
commit1a = create_review(PROJECT1, "review1a on #{PROJECT1}")
commit1b = create_review(PROJECT1, "review1b on #{PROJECT1}")