SubmittedTogether: Also work for already submitted changes
We know which changes were submitted together by querying the database
for the SUBMISSION_ID field.
Change-Id: I4aa7ab9ccd9a51f1a87abea3d762d4b78ac40fbc
Signed-off-by: Stefan Beller <sbeller@google.com>
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/SubmitByFastForwardIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/SubmitByFastForwardIT.java
index 2af3c25..9aa4b34 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/SubmitByFastForwardIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/SubmitByFastForwardIT.java
@@ -49,8 +49,10 @@
PushOneCommit.Result change = createChange();
PushOneCommit.Result change2 = createChange();
- approve(change.getChangeId());
- submit(change2.getChangeId());
+ String id1 = change.getChangeId();
+ String id2 = change2.getChangeId();
+ approve(id1);
+ submit(id2);
RevCommit head = getRemoteHead();
assertThat(head.getId()).isEqualTo(change2.getCommitId());
@@ -59,6 +61,8 @@
assertSubmitter(change2.getChangeId(), 1);
assertPersonEquals(admin.getIdent(), head.getAuthorIdent());
assertPersonEquals(admin.getIdent(), head.getCommitterIdent());
+ assertSubmittedTogether(id1, id1, id2);
+ assertSubmittedTogether(id2, id1, id2);
}
@Test
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/RelatedChanges.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/RelatedChanges.java
index ae1a608..9612f71 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/RelatedChanges.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/RelatedChanges.java
@@ -228,11 +228,9 @@
new TabChangeListCallback(Tab.SAME_TOPIC, info.project(), revision));
} else {
// TODO(sbeller): show only on latest revision
- if (info.status().isOpen()) {
- ChangeApi.change(info.legacyId().get()).view("submitted_together")
- .get(new TabChangeListCallback(Tab.SUBMITTED_TOGETHER,
- info.project(), revision));
- }
+ ChangeApi.change(info.legacyId().get()).view("submitted_together")
+ .get(new TabChangeListCallback(Tab.SUBMITTED_TOGETHER,
+ info.project(), revision));
}
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/SubmittedTogether.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/SubmittedTogether.java
index a4f9fef..dec56a7 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/SubmittedTogether.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/SubmittedTogether.java
@@ -14,15 +14,20 @@
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;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.BadRequestException;
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.git.ChangeSet;
import com.google.gerrit.server.git.MergeSuperSet;
+import com.google.gerrit.server.query.change.ChangeData;
+import com.google.gerrit.server.query.change.InternalChangeQuery;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;
@@ -43,14 +48,17 @@
private final ChangeJson.Factory json;
private final Provider<ReviewDb> dbProvider;
+ private final Provider<InternalChangeQuery> queryProvider;
private final MergeSuperSet mergeSuperSet;
@Inject
SubmittedTogether(ChangeJson.Factory json,
Provider<ReviewDb> dbProvider,
+ Provider<InternalChangeQuery> queryProvider,
MergeSuperSet mergeSuperSet) {
this.json = json;
this.dbProvider = dbProvider;
+ this.queryProvider = queryProvider;
this.mergeSuperSet = mergeSuperSet;
}
@@ -59,16 +67,32 @@
throws AuthException, BadRequestException,
ResourceConflictException, Exception {
try {
- ChangeSet cs = mergeSuperSet.completeChangeSet(dbProvider.get(),
- resource.getChange());
- if (cs.size() > 1) {
- return json.create(EnumSet.of(
- ListChangesOption.CURRENT_REVISION,
- ListChangesOption.CURRENT_COMMIT))
- .format(cs.ids());
+ Change c = resource.getChange();
+ List<Change.Id> ids;
+ if (c.getStatus().isOpen()) {
+ ChangeSet cs = mergeSuperSet.completeChangeSet(dbProvider.get(), c);
+ ids = cs.ids().asList();
+ } 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());
+ }
+ }
} else {
- return Collections.emptyList();
+ // ABANDONED
+ ids = Collections.emptyList();
}
+ if (ids.size() <= 1) {
+ ids = Collections.emptyList();
+ }
+ return json.create(EnumSet.of(
+ ListChangesOption.CURRENT_REVISION,
+ ListChangesOption.CURRENT_COMMIT))
+ .format(ids);
} catch (OrmException | IOException e) {
log.error("Error on getting a ChangeSet", e);
throw e;
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/index/ChangeField.java b/gerrit-server/src/main/java/com/google/gerrit/server/index/ChangeField.java
index e711306..4fa5cd3 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/index/ChangeField.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/index/ChangeField.java
@@ -207,6 +207,21 @@
}
};
+ /** Submission id assigned by MergeOp. */
+ public static final FieldDef<ChangeData, String> SUBMISSIONID =
+ new FieldDef.Single<ChangeData, String>(
+ "submissionid", FieldType.EXACT, false) {
+ @Override
+ public String get(ChangeData input, FillArgs args)
+ throws OrmException {
+ Change c = input.change();
+ if (c == null) {
+ return null;
+ }
+ return c.getSubmissionId();
+ }
+ };
+
/** Last update time since January 1, 1970. */
public static final FieldDef<ChangeData, Timestamp> UPDATED =
new FieldDef.Single<ChangeData, Timestamp>(
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/index/ChangeSchemas.java b/gerrit-server/src/main/java/com/google/gerrit/server/index/ChangeSchemas.java
index a8a97a8..4789a14 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/index/ChangeSchemas.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/index/ChangeSchemas.java
@@ -377,6 +377,42 @@
ChangeField.AUTHOR,
ChangeField.COMMITTER);
+ static final Schema<ChangeData> V25 = schema(
+ ChangeField.LEGACY_ID2,
+ ChangeField.ID,
+ ChangeField.STATUS,
+ ChangeField.PROJECT,
+ ChangeField.PROJECTS,
+ ChangeField.REF,
+ ChangeField.EXACT_TOPIC,
+ ChangeField.FUZZY_TOPIC,
+ ChangeField.UPDATED,
+ ChangeField.FILE_PART,
+ ChangeField.PATH,
+ ChangeField.OWNER,
+ ChangeField.REVIEWER,
+ ChangeField.COMMIT,
+ ChangeField.TR,
+ ChangeField.LABEL,
+ ChangeField.COMMIT_MESSAGE,
+ ChangeField.COMMENT,
+ ChangeField.CHANGE,
+ ChangeField.APPROVAL,
+ ChangeField.MERGEABLE,
+ ChangeField.ADDED,
+ ChangeField.DELETED,
+ ChangeField.DELTA,
+ ChangeField.HASHTAG,
+ ChangeField.COMMENTBY,
+ ChangeField.PATCH_SET,
+ ChangeField.GROUP,
+ ChangeField.SUBMISSIONID,
+ ChangeField.EDITBY,
+ ChangeField.REVIEWEDBY,
+ ChangeField.EXACT_COMMIT,
+ ChangeField.AUTHOR,
+ ChangeField.COMMITTER);
+
private static Schema<ChangeData> schema(Collection<FieldDef<ChangeData, ?>> fields) {
return new Schema<>(ImmutableList.copyOf(fields));
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/InternalChangeQuery.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/InternalChangeQuery.java
index 31c35c2..bb11c05 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/InternalChangeQuery.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/InternalChangeQuery.java
@@ -41,6 +41,7 @@
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.List;
/**
@@ -194,6 +195,14 @@
return query(commit(schema(indexes), id.name()));
}
+ public List<ChangeData> bySubmissionId(String cs) throws OrmException {
+ if (cs.isEmpty()) {
+ return Collections.emptyList();
+ } else {
+ return query(new SubmissionIdPredicate(cs));
+ }
+ }
+
public List<ChangeData> byProjectGroups(Project.NameKey project,
Collection<String> groups) throws OrmException {
List<GroupPredicate> groupPredicates = new ArrayList<>(groups.size());
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/SubmissionIdPredicate.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/SubmissionIdPredicate.java
new file mode 100644
index 0000000..3b2dd94
--- /dev/null
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/SubmissionIdPredicate.java
@@ -0,0 +1,44 @@
+// Copyright (C) 2015 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.server.query.change;
+
+import com.google.gerrit.reviewdb.client.Change;
+import com.google.gerrit.server.index.ChangeField;
+import com.google.gerrit.server.index.IndexPredicate;
+import com.google.gwtorm.server.OrmException;
+
+class SubmissionIdPredicate extends IndexPredicate<ChangeData> {
+
+ SubmissionIdPredicate(String changeSet) {
+ super(ChangeField.SUBMISSIONID, changeSet);
+ }
+
+ @Override
+ public boolean match(ChangeData object) throws OrmException {
+ Change change = object.change();
+ if (change == null) {
+ return false;
+ }
+ if (change.getSubmissionId() == null) {
+ return false;
+ }
+ return getValue().equals(change.getSubmissionId());
+ }
+
+ @Override
+ public int getCost() {
+ return 1;
+ }
+}