diff --git a/Documentation/rest-api-changes.txt b/Documentation/rest-api-changes.txt index 6f9367ddc3..3fc4ea8ded 100644 --- a/Documentation/rest-api-changes.txt +++ b/Documentation/rest-api-changes.txt @@ -6177,6 +6177,12 @@ Callers can find out if there were conflicts by checking the `contains_git_conflicts` field in the link:#change-info[ChangeInfo]. If there are conflicts the cherry-pick change is marked as work-in-progress. +|`topic` |optional| +The topic of the created cherry-picked change. If not set, the default depends +on the source. If the source is a change with a topic, the resulting topic +of the cherry-picked change will be {source_change_topic}-{destination_branch}. +Otherwise, if the source change has no topic, or the source is a commit, +the created change will have no topic. |=========================== [[comment-info]] diff --git a/java/com/google/gerrit/extensions/api/changes/CherryPickInput.java b/java/com/google/gerrit/extensions/api/changes/CherryPickInput.java index 5ac67e7def..4ec6f01ec6 100644 --- a/java/com/google/gerrit/extensions/api/changes/CherryPickInput.java +++ b/java/com/google/gerrit/extensions/api/changes/CherryPickInput.java @@ -29,4 +29,5 @@ public class CherryPickInput { public boolean keepReviewers; public boolean allowConflicts; + public String topic; } diff --git a/java/com/google/gerrit/server/restapi/change/CherryPickChange.java b/java/com/google/gerrit/server/restapi/change/CherryPickChange.java index 82b138dfc2..596011798c 100644 --- a/java/com/google/gerrit/server/restapi/change/CherryPickChange.java +++ b/java/com/google/gerrit/server/restapi/change/CherryPickChange.java @@ -175,7 +175,6 @@ public class CherryPickChange { null, null, null, - null, null); } @@ -217,7 +216,6 @@ public class CherryPickChange { null, null, null, - null, null); } @@ -235,7 +233,6 @@ public class CherryPickChange { * @param ignoreIdenticalTree When false, we throw an error when trying to cherry-pick creates an * empty commit. When true, we allow creation of an empty commit. * @param timestamp the current timestamp. - * @param topic Topic name for the change created. * @param revertedChange The id of the change that is reverted. This is used for the "revertOf" * field to mark the created cherry pick change as "revertOf" the original change that was * reverted. @@ -263,7 +260,6 @@ public class CherryPickChange { BranchNameKey dest, boolean ignoreIdenticalTree, Timestamp timestamp, - @Nullable String topic, @Nullable Change.Id revertedChange, @Nullable ObjectId changeIdForNewChange, @Nullable Change.Id idForNewChange, @@ -381,8 +377,11 @@ public class CherryPickChange { } else { // Change key not found on destination branch. We can create a new // change. - String newTopic = topic; - if (topic == null + String newTopic = null; + if (input.topic != null) { + newTopic = Strings.emptyToNull(input.topic.trim()); + } + if (newTopic == null && sourceChange != null && !Strings.isNullOrEmpty(sourceChange.getTopic())) { newTopic = sourceChange.getTopic() + "-" + newDest.shortName(); diff --git a/java/com/google/gerrit/server/restapi/change/RevertSubmission.java b/java/com/google/gerrit/server/restapi/change/RevertSubmission.java index 52cc46f048..e7da89ad19 100644 --- a/java/com/google/gerrit/server/restapi/change/RevertSubmission.java +++ b/java/com/google/gerrit/server/restapi/change/RevertSubmission.java @@ -20,6 +20,7 @@ import static com.google.gerrit.server.permissions.RefPermission.CREATE_CHANGE; import static com.google.gerrit.server.project.ProjectCache.illegalState; import static java.util.Objects.requireNonNull; +import com.google.common.base.Strings; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; import com.google.common.flogger.FluentLogger; @@ -195,6 +196,9 @@ public class RevertSubmission } private String createTopic(String topic, String submissionId) { + if (topic != null) { + topic = Strings.emptyToNull(topic.trim()); + } if (topic == null) { return String.format( "revert-%s-%s", submissionId, RandomStringUtils.randomAlphabetic(10).toUpperCase()); @@ -321,12 +325,7 @@ public class RevertSubmission bu.addOp( changeNotes.getChange().getId(), new CreateCherryPickOp( - revCommitId, - revertInput.topic, - generatedChangeId, - cherryPickRevertChangeId, - groupName, - timestamp)); + revCommitId, generatedChangeId, cherryPickRevertChangeId, groupName, timestamp)); bu.addOp(changeNotes.getChange().getId(), new PostRevertedMessageOp(generatedChangeId)); bu.addOp( cherryPickRevertChangeId, @@ -356,6 +355,7 @@ public class RevertSubmission cherryPickInput.notifyDetails = revertInput.notifyDetails; cherryPickInput.parent = 1; cherryPickInput.keepReviewers = true; + cherryPickInput.topic = revertInput.topic; return cherryPickInput; } @@ -570,7 +570,6 @@ public class RevertSubmission private class CreateCherryPickOp implements BatchUpdateOp { private final ObjectId revCommitId; - private final String topic; private final ObjectId computedChangeId; private final Change.Id cherryPickRevertChangeId; private final String groupName; @@ -578,13 +577,11 @@ public class RevertSubmission CreateCherryPickOp( ObjectId revCommitId, - String topic, ObjectId computedChangeId, Change.Id cherryPickRevertChangeId, String groupName, Timestamp timestamp) { this.revCommitId = revCommitId; - this.topic = topic; this.computedChangeId = computedChangeId; this.cherryPickRevertChangeId = cherryPickRevertChangeId; this.groupName = groupName; @@ -604,7 +601,6 @@ public class RevertSubmission change.getProject(), RefNames.fullName(cherryPickInput.destination)), true, timestamp, - topic, change.getId(), computedChangeId, cherryPickRevertChangeId, diff --git a/javatests/com/google/gerrit/acceptance/api/project/CommitIT.java b/javatests/com/google/gerrit/acceptance/api/project/CommitIT.java index 04625c58df..e67770c3ec 100644 --- a/javatests/com/google/gerrit/acceptance/api/project/CommitIT.java +++ b/javatests/com/google/gerrit/acceptance/api/project/CommitIT.java @@ -169,6 +169,21 @@ public class CommitIT extends AbstractDaemonTest { assertThat(revInfo.commit.message).isEqualTo(input.message + "\n"); } + @Test + public void cherryPickCommitWithSetTopic() throws Exception { + String branch = "foo"; + RevCommit revCommit = createChange().getCommit(); + gApi.projects().name(project.get()).branch(branch).create(new BranchInput()); + CherryPickInput input = new CherryPickInput(); + input.destination = branch; + input.topic = "topic"; + String changeId = + gApi.projects().name(project.get()).commit(revCommit.name()).cherryPick(input).get().id; + + ChangeInfo changeInfo = gApi.changes().id(changeId).get(); + assertThat(changeInfo.topic).isEqualTo(input.topic); + } + private IncludedInInfo getIncludedIn(ObjectId id) throws Exception { return gApi.projects().name(project.get()).commit(id.name()).includedIn(); } diff --git a/javatests/com/google/gerrit/acceptance/api/revision/RevisionIT.java b/javatests/com/google/gerrit/acceptance/api/revision/RevisionIT.java index 70fcfc4d70..239db93566 100644 --- a/javatests/com/google/gerrit/acceptance/api/revision/RevisionIT.java +++ b/javatests/com/google/gerrit/acceptance/api/revision/RevisionIT.java @@ -408,6 +408,19 @@ public class RevisionIT extends AbstractDaemonTest { cherry.current().submit(); } + @Test + public void cherryPickWithSetTopic() throws Exception { + PushOneCommit.Result r = pushTo("refs/for/master"); + CherryPickInput in = new CherryPickInput(); + in.destination = "foo"; + in.topic = "topic"; + gApi.projects().name(project.get()).branch(in.destination).create(new BranchInput()); + ChangeApi orig = gApi.changes().id(project.get() + "~master~" + r.getChangeId()); + + ChangeApi cherry = orig.revision(r.getCommit().name()).cherryPick(in); + assertThat(cherry.get().topic).isEqualTo("topic"); + } + @Test public void cherryPickWorkInProgressChange() throws Exception { PushOneCommit.Result r = pushTo("refs/for/master%wip");