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:
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user