SubmitByMergeIfNecessary: Test indirectly related changes
When we submit a change all its ancestors are also submitted. We need to make sure that the ancestors also follow the submitWholeTopic rule. That is if they have a topic all the changes with their topic needs to be integrated as well. This first two tests chain changes over 3 topics and the change in the first and last topic are not related to each other except for having a dependency over the second topic. Make sure all of these changes are merged or none are merged. The last two changes are testing the ancestor submission. The ancestors may have changes which are targeted at the same branch or another branch. We only collect the changes on the same branch. Even if there are open and reviewd changes on other branches, we should ignore them when submitting ancestors. Change-Id: I7c6e5e864a3a0317104724621a29f6608646ad93
This commit is contained in:
@@ -186,6 +186,14 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
|
||||
return push.to("refs/for/master/" + topic);
|
||||
}
|
||||
|
||||
protected PushOneCommit.Result createChange(TestRepository<?> repo,
|
||||
String branch, String subject, String fileName, String content,
|
||||
String topic) throws Exception {
|
||||
PushOneCommit push =
|
||||
pushFactory.create(db, admin.getIdent(), repo, subject, fileName, content);
|
||||
return push.to("refs/for/" + branch + "/" + name(topic));
|
||||
}
|
||||
|
||||
protected void submit(String changeId) throws Exception {
|
||||
submit(changeId, HttpStatus.SC_OK);
|
||||
}
|
||||
@@ -303,12 +311,19 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
|
||||
return getHead(repo, "HEAD");
|
||||
}
|
||||
|
||||
protected RevCommit getRemoteHead() throws IOException {
|
||||
protected RevCommit getRemoteHead(Project.NameKey project, String branch)
|
||||
throws IOException {
|
||||
try (Repository repo = repoManager.openRepository(project)) {
|
||||
return getHead(repo, "refs/heads/master");
|
||||
return getHead(repo, "refs/heads/" + branch);
|
||||
}
|
||||
}
|
||||
|
||||
protected RevCommit getRemoteHead()
|
||||
throws IOException {
|
||||
return getRemoteHead(project, "master");
|
||||
}
|
||||
|
||||
|
||||
protected List<RevCommit> getRemoteLog(Project.NameKey project, String branch)
|
||||
throws IOException {
|
||||
try (Repository repo = repoManager.openRepository(project);
|
||||
|
@@ -3,8 +3,11 @@ package com.google.gerrit.acceptance.rest.change;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import com.google.gerrit.acceptance.PushOneCommit;
|
||||
import com.google.gerrit.extensions.api.projects.BranchInput;
|
||||
import com.google.gerrit.extensions.client.SubmitType;
|
||||
import com.google.gerrit.reviewdb.client.Project;
|
||||
|
||||
import org.eclipse.jgit.junit.TestRepository;
|
||||
import org.eclipse.jgit.revwalk.RevCommit;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -45,8 +48,7 @@ public class SubmitByMergeIfNecessaryIT extends AbstractSubmitByMerge {
|
||||
submitStatusOnly(change3.getChangeId());
|
||||
submit(change4.getChangeId());
|
||||
|
||||
List<RevCommit> log = getRemoteLog();
|
||||
RevCommit tip = log.get(0);
|
||||
RevCommit tip = getRemoteLog().get(0);
|
||||
assertThat(tip.getParent(1).getShortMessage()).isEqualTo(
|
||||
change4.getCommit().getShortMessage());
|
||||
|
||||
@@ -60,4 +62,226 @@ public class SubmitByMergeIfNecessaryIT extends AbstractSubmitByMerge {
|
||||
|
||||
assertThat(tip.getParent(0).getId()).isEqualTo(initialHead.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void submitChangesAcrossRepos() throws Exception {
|
||||
Project.NameKey p1 = createProject("project-where-we-submit");
|
||||
Project.NameKey p2 = createProject("project-impacted-via-topic");
|
||||
Project.NameKey p3 = createProject("project-impacted-indirectly-via-topic");
|
||||
|
||||
RevCommit initialHead2 = getRemoteHead(p2, "master");
|
||||
RevCommit initialHead3 = getRemoteHead(p3, "master");
|
||||
|
||||
TestRepository<?> repo1 = cloneProject(p1);
|
||||
TestRepository<?> repo2 = cloneProject(p2);
|
||||
TestRepository<?> repo3 = cloneProject(p3);
|
||||
|
||||
PushOneCommit.Result change1a = createChange(repo1, "master",
|
||||
"An ancestor of the change we want to submit",
|
||||
"a.txt", "1", "dependent-topic");
|
||||
PushOneCommit.Result change1b = createChange(repo1, "master",
|
||||
"We're interested in submitting this change",
|
||||
"a.txt", "2", "topic-to-submit");
|
||||
|
||||
PushOneCommit.Result change2a = createChange(repo2, "master",
|
||||
"indirection level 1",
|
||||
"a.txt", "1", "topic-indirect");
|
||||
PushOneCommit.Result change2b = createChange(repo2, "master",
|
||||
"should go in with first change",
|
||||
"a.txt", "2", "dependent-topic");
|
||||
|
||||
PushOneCommit.Result change3 = createChange(repo3, "master",
|
||||
"indirection level 2",
|
||||
"a.txt", "1", "topic-indirect");
|
||||
|
||||
approve(change1a.getChangeId());
|
||||
approve(change2a.getChangeId());
|
||||
approve(change2b.getChangeId());
|
||||
approve(change3.getChangeId());
|
||||
submit(change1b.getChangeId());
|
||||
|
||||
RevCommit tip1 = getRemoteLog(p1, "master").get(0);
|
||||
RevCommit tip2 = getRemoteLog(p2, "master").get(0);
|
||||
RevCommit tip3 = getRemoteLog(p3, "master").get(0);
|
||||
|
||||
assertThat(tip1.getShortMessage()).isEqualTo(
|
||||
change1b.getCommit().getShortMessage());
|
||||
|
||||
if (isSubmitWholeTopicEnabled()) {
|
||||
assertThat(tip2.getShortMessage()).isEqualTo(
|
||||
change2b.getCommit().getShortMessage());
|
||||
assertThat(tip3.getShortMessage()).isEqualTo(
|
||||
change3.getCommit().getShortMessage());
|
||||
} else {
|
||||
assertThat(tip2.getShortMessage()).isEqualTo(
|
||||
initialHead2.getShortMessage());
|
||||
assertThat(tip3.getShortMessage()).isEqualTo(
|
||||
initialHead3.getShortMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void submitChangesAcrossReposBlocked() throws Exception {
|
||||
Project.NameKey p1 = createProject("project-where-we-submit");
|
||||
Project.NameKey p2 = createProject("project-impacted-via-topic");
|
||||
Project.NameKey p3 = createProject("project-impacted-indirectly-via-topic");
|
||||
|
||||
TestRepository<?> repo1 = cloneProject(p1);
|
||||
TestRepository<?> repo2 = cloneProject(p2);
|
||||
TestRepository<?> repo3 = cloneProject(p3);
|
||||
|
||||
RevCommit initialHead1 = getRemoteHead(p1, "master");
|
||||
RevCommit initialHead2 = getRemoteHead(p2, "master");
|
||||
RevCommit initialHead3 = getRemoteHead(p3, "master");
|
||||
|
||||
PushOneCommit.Result change1a = createChange(repo1, "master",
|
||||
"An ancestor of the change we want to submit",
|
||||
"a.txt", "1", "dependent-topic");
|
||||
PushOneCommit.Result change1b = createChange(repo1, "master",
|
||||
"we're interested to submit this change",
|
||||
"a.txt", "2", "topic-to-submit");
|
||||
|
||||
PushOneCommit.Result change2a = createChange(repo2, "master",
|
||||
"indirection level 2a",
|
||||
"a.txt", "1", "topic-indirect");
|
||||
PushOneCommit.Result change2b = createChange(repo2, "master",
|
||||
"should go in with first change",
|
||||
"a.txt", "2", "dependent-topic");
|
||||
|
||||
PushOneCommit.Result change3 = createChange(repo3, "master",
|
||||
"indirection level 2b",
|
||||
"a.txt", "1", "topic-indirect");
|
||||
|
||||
// Create a merge conflict for change3 which is only indirectly related
|
||||
// via topics.
|
||||
repo3.reset(initialHead3);
|
||||
PushOneCommit.Result change3Conflict = createChange(repo3, "master",
|
||||
"conflicting change",
|
||||
"a.txt", "2\n2", "conflicting-topic");
|
||||
submit(change3Conflict.getChangeId());
|
||||
RevCommit tipConflict = getRemoteLog(p3, "master").get(0);
|
||||
assertThat(tipConflict.getShortMessage()).isEqualTo(
|
||||
change3Conflict.getCommit().getShortMessage());
|
||||
|
||||
approve(change1a.getChangeId());
|
||||
approve(change2a.getChangeId());
|
||||
approve(change2b.getChangeId());
|
||||
approve(change3.getChangeId());
|
||||
|
||||
if (isSubmitWholeTopicEnabled()) {
|
||||
submitWithConflict(change1b.getChangeId());
|
||||
} else {
|
||||
submit(change1b.getChangeId());
|
||||
}
|
||||
|
||||
RevCommit tip1 = getRemoteLog(p1, "master").get(0);
|
||||
RevCommit tip2 = getRemoteLog(p2, "master").get(0);
|
||||
RevCommit tip3 = getRemoteLog(p3, "master").get(0);
|
||||
if (isSubmitWholeTopicEnabled()) {
|
||||
assertThat(tip1.getShortMessage()).isEqualTo(
|
||||
initialHead1.getShortMessage());
|
||||
assertThat(tip2.getShortMessage()).isEqualTo(
|
||||
initialHead2.getShortMessage());
|
||||
assertThat(tip3.getShortMessage()).isEqualTo(
|
||||
change3Conflict.getCommit().getShortMessage());
|
||||
} else {
|
||||
assertThat(tip1.getShortMessage()).isEqualTo(
|
||||
change1b.getCommit().getShortMessage());
|
||||
assertThat(tip2.getShortMessage()).isEqualTo(
|
||||
initialHead2.getShortMessage());
|
||||
assertThat(tip3.getShortMessage()).isEqualTo(
|
||||
change3Conflict.getCommit().getShortMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void submitWithMergedAncestorsOnOtherBranch() throws Exception {
|
||||
PushOneCommit.Result change1 = createChange(testRepo, "master",
|
||||
"base commit",
|
||||
"a.txt", "1", "");
|
||||
submit(change1.getChangeId());
|
||||
|
||||
gApi.projects()
|
||||
.name(project.get())
|
||||
.branch("branch")
|
||||
.create(new BranchInput());
|
||||
|
||||
PushOneCommit.Result change2 = createChange(testRepo, "master",
|
||||
"We want to commit this to master first",
|
||||
"a.txt", "2", "");
|
||||
|
||||
submit(change2.getChangeId());
|
||||
|
||||
RevCommit tip1 = getRemoteLog(project, "master").get(0);
|
||||
assertThat(tip1.getShortMessage()).isEqualTo(
|
||||
change2.getCommit().getShortMessage());
|
||||
|
||||
RevCommit tip2 = getRemoteLog(project, "branch").get(0);
|
||||
assertThat(tip2.getShortMessage()).isEqualTo(
|
||||
change1.getCommit().getShortMessage());
|
||||
|
||||
PushOneCommit.Result change3 = createChange(testRepo, "branch",
|
||||
"This commit is based on master, which includes change2, "
|
||||
+ "but is targeted at branch, which doesn't include it.",
|
||||
"a.txt", "3", "");
|
||||
|
||||
submit(change3.getChangeId());
|
||||
|
||||
List<RevCommit> log3 = getRemoteLog(project, "branch");
|
||||
assertThat(log3.get(0).getShortMessage()).isEqualTo(
|
||||
change3.getCommit().getShortMessage());
|
||||
assertThat(log3.get(1).getShortMessage()).isEqualTo(
|
||||
change2.getCommit().getShortMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void submitWithOpenAncestorsOnOtherBranch() throws Exception {
|
||||
PushOneCommit.Result change1 = createChange(testRepo, "master",
|
||||
"base commit",
|
||||
"a.txt", "1", "");
|
||||
submit(change1.getChangeId());
|
||||
|
||||
gApi.projects()
|
||||
.name(project.get())
|
||||
.branch("branch")
|
||||
.create(new BranchInput());
|
||||
|
||||
PushOneCommit.Result change2 = createChange(testRepo, "master",
|
||||
"We want to commit this to master first",
|
||||
"a.txt", "2", "");
|
||||
|
||||
approve(change2.getChangeId());
|
||||
|
||||
RevCommit tip1 = getRemoteLog(project, "master").get(0);
|
||||
assertThat(tip1.getShortMessage()).isEqualTo(
|
||||
change1.getCommit().getShortMessage());
|
||||
|
||||
RevCommit tip2 = getRemoteLog(project, "branch").get(0);
|
||||
assertThat(tip2.getShortMessage()).isEqualTo(
|
||||
change1.getCommit().getShortMessage());
|
||||
|
||||
PushOneCommit.Result change3a = createChange(testRepo, "branch",
|
||||
"This commit is based on change2 pending for master, "
|
||||
+ "but is targeted itself at branch, which doesn't include it.",
|
||||
"a.txt", "3", "a-topic-here");
|
||||
|
||||
Project.NameKey p3 = createProject("project-related-to-change3");
|
||||
TestRepository<?> repo3 = cloneProject(p3);
|
||||
RevCommit initialHead = getRemoteHead(p3, "master");
|
||||
PushOneCommit.Result change3b = createChange(repo3, "master",
|
||||
"some accompanying changes for change3a in another repo "
|
||||
+ "tied together via topic",
|
||||
"a.txt", "1", "a-topic-here");
|
||||
approve(change3b.getChangeId());
|
||||
|
||||
submitWithConflict(change3a.getChangeId());
|
||||
|
||||
RevCommit tipbranch = getRemoteLog(project, "branch").get(0);
|
||||
assertThat(tipbranch.getShortMessage()).isEqualTo(
|
||||
change1.getCommit().getShortMessage());
|
||||
|
||||
RevCommit tipmaster = getRemoteLog(p3, "master").get(0);
|
||||
assertThat(tipmaster.getShortMessage()).isEqualTo(
|
||||
initialHead.getShortMessage());
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user