use of com.google.gerrit.server.query.change.ChangeData in project gerrit by GerritCodeReview.
the class MergeSuperSet method topicClosure.
/**
* Completes {@code changeSet} with any additional changes from its topics
*
* <p>{@link #completeChangeSetIncludingTopics} calls this repeatedly, alternating with {@link
* MergeSuperSetComputation#completeWithoutTopic(MergeOpRepoManager, ChangeSet, CurrentUser)}, to
* discover what additional changes should be submitted with a change until the set stops growing.
*
* <p>{@code topicsSeen} and {@code visibleTopicsSeen} keep track of topics already explored to
* avoid wasted work.
*
* @return the resulting larger {@link ChangeSet}
*/
private ChangeSet topicClosure(ChangeSet changeSet, CurrentUser user, Set<String> topicsSeen, Set<String> visibleTopicsSeen) throws PermissionBackendException {
List<ChangeData> visibleChanges = new ArrayList<>();
List<ChangeData> nonVisibleChanges = new ArrayList<>();
for (ChangeData cd : changeSet.changes()) {
visibleChanges.add(cd);
String topic = cd.change().getTopic();
if (Strings.isNullOrEmpty(topic) || visibleTopicsSeen.contains(topic)) {
continue;
}
for (ChangeData topicCd : byTopicOpen(topic)) {
if (canRead(user, topicCd)) {
visibleChanges.add(topicCd);
} else {
nonVisibleChanges.add(topicCd);
}
}
topicsSeen.add(topic);
visibleTopicsSeen.add(topic);
}
for (ChangeData cd : changeSet.nonVisibleChanges()) {
nonVisibleChanges.add(cd);
String topic = cd.change().getTopic();
if (Strings.isNullOrEmpty(topic) || topicsSeen.contains(topic)) {
continue;
}
for (ChangeData topicCd : byTopicOpen(topic)) {
nonVisibleChanges.add(topicCd);
}
topicsSeen.add(topic);
}
return new ChangeSet(visibleChanges, nonVisibleChanges);
}
use of com.google.gerrit.server.query.change.ChangeData in project gerrit by GerritCodeReview.
the class MergeSuperSet method completeChangeSet.
/**
* Gets the ChangeSet of this {@code change} based on visiblity of the {@code user}. if
* change.submitWholeTopic is true, we return the topic closure as well as the dependent changes
* of the topic closure. Otherwise, we return just the dependent changes.
*
* @param change the change for which we get the dependent changes / topic closure.
* @param user the current user for visibility purposes.
* @param includingTopicClosure when true, return as if change.submitWholeTopic = true, so we
* return the topic closure.
* @return {@link ChangeSet} object that represents the dependent changes and/or topic closure of
* the requested change.
*/
public ChangeSet completeChangeSet(Change change, CurrentUser user, boolean includingTopicClosure) throws IOException, PermissionBackendException {
try {
if (orm == null) {
orm = repoManagerProvider.get();
closeOrm = true;
}
ChangeData cd = changeDataFactory.create(change.getProject(), change.getId());
boolean visible = false;
if (cd != null) {
if (projectCache.get(cd.project()).map(ProjectState::statePermitsRead).orElse(false)) {
try {
permissionBackend.user(user).change(cd).check(ChangePermission.READ);
visible = true;
} catch (AuthException e) {
// Do nothing.
}
}
}
ChangeSet changeSet = new ChangeSet(cd, visible);
if (wholeTopicEnabled(cfg) || includingTopicClosure) {
return completeChangeSetIncludingTopics(changeSet, user);
}
try (TraceContext traceContext = PluginContext.newTrace(mergeSuperSetComputation)) {
return mergeSuperSetComputation.get().completeWithoutTopic(orm, changeSet, user);
}
} finally {
if (closeOrm && orm != null) {
orm.close();
orm = null;
}
}
}
use of com.google.gerrit.server.query.change.ChangeData in project gerrit by GerritCodeReview.
the class LocalMergeSuperSetComputation method completeWithoutTopic.
@Override
public ChangeSet completeWithoutTopic(MergeOpRepoManager orm, ChangeSet changeSet, CurrentUser user) throws IOException {
Collection<ChangeData> visibleChanges = new ArrayList<>();
Collection<ChangeData> nonVisibleChanges = new ArrayList<>();
// For each target branch we run a separate rev walk to find open changes
// reachable from changes already in the merge super set.
ImmutableSet<BranchNameKey> branches = byBranch(Iterables.concat(changeSet.changes(), changeSet.nonVisibleChanges())).keySet();
ImmutableListMultimap<BranchNameKey, ChangeData> visibleChangesPerBranch = byBranch(changeSet.changes());
ImmutableListMultimap<BranchNameKey, ChangeData> nonVisibleChangesPerBranch = byBranch(changeSet.nonVisibleChanges());
for (BranchNameKey branchNameKey : branches) {
OpenRepo or = getRepo(orm, branchNameKey.project());
List<RevCommit> visibleCommits = new ArrayList<>();
List<RevCommit> nonVisibleCommits = new ArrayList<>();
for (ChangeData cd : visibleChangesPerBranch.get(branchNameKey)) {
if (submitType(cd) == SubmitType.CHERRY_PICK) {
visibleChanges.add(cd);
} else {
visibleCommits.add(or.rw.parseCommit(cd.currentPatchSet().commitId()));
}
}
for (ChangeData cd : nonVisibleChangesPerBranch.get(branchNameKey)) {
if (submitType(cd) == SubmitType.CHERRY_PICK) {
nonVisibleChanges.add(cd);
} else {
nonVisibleCommits.add(or.rw.parseCommit(cd.currentPatchSet().commitId()));
}
}
Set<String> visibleHashes = walkChangesByHashes(visibleCommits, Collections.emptySet(), or, branchNameKey);
Set<String> nonVisibleHashes = walkChangesByHashes(nonVisibleCommits, visibleHashes, or, branchNameKey);
ChangeSet partialSet = byCommitsOnBranchNotMerged(or, branchNameKey, visibleHashes, nonVisibleHashes, user);
Iterables.addAll(visibleChanges, partialSet.changes());
Iterables.addAll(nonVisibleChanges, partialSet.nonVisibleChanges());
}
return new ChangeSet(visibleChanges, nonVisibleChanges);
}
use of com.google.gerrit.server.query.change.ChangeData in project gerrit by GerritCodeReview.
the class AbstractSubmitOnPush method mergeOnPushToBranchWithNewPatchset.
@Test
public void mergeOnPushToBranchWithNewPatchset() throws Exception {
projectOperations.project(project).forUpdate().add(allow(Permission.PUSH).ref("refs/heads/master").group(adminGroupUuid())).update();
PushOneCommit.Result r = pushTo("refs/for/master");
r.assertOkStatus();
RevCommit c1 = r.getCommit();
PatchSet.Id psId1 = r.getPatchSetId();
assertThat(psId1.get()).isEqualTo(1);
PushOneCommit push = pushFactory.create(admin.newIdent(), testRepo, PushOneCommit.SUBJECT, "b.txt", "anotherContent", r.getChangeId());
r = push.to("refs/heads/master");
r.assertOkStatus();
ChangeData cd = r.getChange();
RevCommit c2 = r.getCommit();
assertThat(cd.change().isMerged()).isTrue();
PatchSet.Id psId2 = cd.change().currentPatchSetId();
assertThat(psId2.get()).isEqualTo(2);
assertCommit(project, "refs/heads/master");
assertSubmitApproval(psId2);
assertThat(cd.patchSets()).hasSize(2);
assertThat(cd.patchSet(psId1).commitId()).isEqualTo(c1);
assertThat(cd.patchSet(psId2).commitId()).isEqualTo(c2);
}
use of com.google.gerrit.server.query.change.ChangeData in project gerrit by GerritCodeReview.
the class AbstractSubmitOnPush method submitOnPushNewPatchSet.
@Test
public void submitOnPushNewPatchSet() throws Exception {
PushOneCommit.Result r = push("refs/for/master", PushOneCommit.SUBJECT, "a.txt", "some content");
projectOperations.project(project).forUpdate().add(allow(Permission.SUBMIT).ref("refs/for/refs/heads/master").group(adminGroupUuid())).update();
r = push("refs/for/master%submit", PushOneCommit.SUBJECT, "a.txt", "other content", r.getChangeId());
r.assertOkStatus();
r.assertChange(Change.Status.MERGED, null, admin);
ChangeData cd = Iterables.getOnlyElement(queryProvider.get().byKeyPrefix(r.getChangeId()));
assertThat(cd.patchSets()).hasSize(2);
assertSubmitApproval(r.getPatchSetId());
assertCommit(project, "refs/heads/master");
}
Aggregations