Fix SubmittedTogether for merged changes

The current code NPEs when the submission ID is missing, as it is on
all changes created prior to the schema upgrade. It also sends a query
to the secondary index even when the field doesn't exist in the
schema, which depending on the index implementation may also be an
error. Bypass both these cases in InternalChangeQuery, just returning
an empty list.

Fix the ordering of results to more closely match the ordering prior
to merge, using the same WalkSorter we currently use for the Related
Changes tab.

Add a test.

Change-Id: I13211bcd037596e51c2bd51d5e2718825448d068
This commit is contained in:
Dave Borowitz
2015-10-12 12:25:43 -04:00
parent 03e25351d4
commit 96491a14a0
3 changed files with 87 additions and 16 deletions

View File

@@ -14,7 +14,6 @@
package com.google.gerrit.server.change;
import com.google.common.collect.Lists;
import com.google.gerrit.extensions.client.ChangeStatus;
import com.google.gerrit.extensions.client.ListChangesOption;
import com.google.gerrit.extensions.common.ChangeInfo;
@@ -24,6 +23,7 @@ import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.RestReadView;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.change.WalkSorter.PatchSetData;
import com.google.gerrit.server.git.ChangeSet;
import com.google.gerrit.server.git.MergeSuperSet;
import com.google.gerrit.server.query.change.ChangeData;
@@ -37,6 +37,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
@@ -50,16 +51,19 @@ public class SubmittedTogether implements RestReadView<ChangeResource> {
private final Provider<ReviewDb> dbProvider;
private final Provider<InternalChangeQuery> queryProvider;
private final MergeSuperSet mergeSuperSet;
private final Provider<WalkSorter> sorter;
@Inject
SubmittedTogether(ChangeJson.Factory json,
Provider<ReviewDb> dbProvider,
Provider<InternalChangeQuery> queryProvider,
MergeSuperSet mergeSuperSet) {
MergeSuperSet mergeSuperSet,
Provider<WalkSorter> sorter) {
this.json = json;
this.dbProvider = dbProvider;
this.queryProvider = queryProvider;
this.mergeSuperSet = mergeSuperSet;
this.sorter = sorter;
}
@Override
@@ -70,21 +74,11 @@ public class SubmittedTogether implements RestReadView<ChangeResource> {
Change c = resource.getChange();
List<Change.Id> ids;
if (c.getStatus().isOpen()) {
ChangeSet cs = mergeSuperSet.completeChangeSet(dbProvider.get(), c);
ids = cs.ids().asList();
ids = getForOpenChange(c);
} else if (c.getStatus().asChangeStatus() == ChangeStatus.MERGED) {
ids = Lists.newArrayList();
String subId = c.getSubmissionId();
if (subId.isEmpty()) {
ids = Collections.emptyList();
} else {
for (ChangeData cd : queryProvider.get().bySubmissionId(subId)) {
ids.add(cd.getId());
}
}
ids = getForMergedChange(c);
} else {
// ABANDONED
ids = Collections.emptyList();
ids = getForAbandonedChange();
}
if (ids.size() <= 1) {
ids = Collections.emptyList();
@@ -98,4 +92,31 @@ public class SubmittedTogether implements RestReadView<ChangeResource> {
throw e;
}
}
private List<Change.Id> getForOpenChange(Change c)
throws OrmException, IOException {
ChangeSet cs = mergeSuperSet.completeChangeSet(dbProvider.get(), c);
return cs.ids().asList();
}
private List<Change.Id> getForMergedChange(Change c)
throws OrmException, IOException {
String subId = c.getSubmissionId();
List<ChangeData> cds = queryProvider.get().bySubmissionId(subId);
if (cds.size() <= 1) {
// Bypass WalkSorter to avoid opening the repo just to populate the commit
// field in PatchSetData that we would throw out in apply() above anyway.
return Collections.emptyList();
}
List<Change.Id> ids = new ArrayList<>(cds.size());
for (PatchSetData psd : sorter.get().sort(cds)) {
ids.add(psd.data().getId());
}
return ids;
}
private List<Change.Id> getForAbandonedChange() {
return Collections.emptyList();
}
}