Fix "Conflicts With" when other change is a merge-commit
The "Conflicts With" list often didn't consider the merge-commit changes
because the list of changed files for a merge commit consists of only
those files which had a conflict during that merge and we only
considered those changes with overlapping file-set as potential conflict
candidates.
Check for all open merge-commit changes if they will conflict with the
current change. This fix is reasonable as the number of merge-commits in
review is usually low.
Note that this only fixes the case when a candidate for the "Conflicts
With" list is a merge commit. The case when the current change, on which
the "Conflicts With" is computed, is a merge commit requires a different
fix.
Bug: issue 3052
Change-Id: I137497fe1bbe262406e693cfd5fdec2ad4a67722
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
index c9d7e6c..250b1f295 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
@@ -99,6 +99,7 @@
public static final String FIELD_HASHTAG = "hashtag";
public static final String FIELD_LABEL = "label";
public static final String FIELD_LIMIT = "limit";
+ public static final String FIELD_MERGE = "merge";
public static final String FIELD_MERGEABLE = "mergeable";
public static final String FIELD_MESSAGE = "message";
public static final String FIELD_OWNER = "owner";
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ConflictsPredicate.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ConflictsPredicate.java
index 2070746..95d0422 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ConflictsPredicate.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ConflictsPredicate.java
@@ -81,7 +81,32 @@
new ProjectPredicate(c.getProject().get()));
predicatesForOneChange.add(
new RefPredicate(c.getDest().get()));
- predicatesForOneChange.add(or(filePredicates));
+
+ OperatorPredicate<ChangeData> isMerge = new OperatorPredicate<ChangeData>(
+ ChangeQueryBuilder.FIELD_MERGE, value) {
+
+ @Override
+ public boolean match(ChangeData cd) throws OrmException {
+ ObjectId id = ObjectId.fromString(
+ cd.currentPatchSet().getRevision().get());
+ try (Repository repo =
+ args.repoManager.openRepository(cd.change().getProject());
+ RevWalk rw = CodeReviewCommit.newRevWalk(repo)) {
+ RevCommit commit = rw.parseCommit(id);
+ return commit.getParentCount() > 1;
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ @Override
+ public int getCost() {
+ return 2;
+ }
+ };
+
+ predicatesForOneChange.add(or(or(filePredicates), isMerge));
+
predicatesForOneChange.add(new OperatorPredicate<ChangeData>(
ChangeQueryBuilder.FIELD_CONFLICTS, value) {