diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/revision/RevisionIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/revision/RevisionIT.java index d60a9044cb..a4dac63791 100644 --- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/revision/RevisionIT.java +++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/revision/RevisionIT.java @@ -25,8 +25,10 @@ import com.google.gerrit.acceptance.SshSession; import com.google.gerrit.acceptance.TestAccount; import com.google.gerrit.acceptance.git.PushOneCommit; import com.google.gerrit.extensions.api.GerritApi; +import com.google.gerrit.extensions.api.changes.ChangeApi; +import com.google.gerrit.extensions.api.changes.CherryPickInput; import com.google.gerrit.extensions.api.changes.ReviewInput; -import com.google.gerrit.extensions.api.changes.RevisionApi; +import com.google.gerrit.extensions.api.projects.BranchInput; import com.google.gerrit.extensions.restapi.RestApiException; import com.google.gerrit.reviewdb.client.Project; import com.google.gerrit.reviewdb.server.ReviewDb; @@ -63,12 +65,13 @@ public class RevisionIT extends AbstractDaemonTest { private TestAccount admin; private Git git; private ReviewDb db; + private Project.NameKey project; @Before public void setUp() throws Exception { admin = accounts.admin(); initSsh(admin); - Project.NameKey project = new Project.NameKey("p"); + project = new Project.NameKey("p"); SshSession sshSession = new SshSession(server, admin); createProject(sshSession, project.get()); git = cloneProject(sshSession.getUrl() + "/" + project.get()); @@ -106,11 +109,14 @@ public class RevisionIT extends AbstractDaemonTest { public void submit() throws GitAPIException, IOException, RestApiException { PushOneCommit.Result r = createChange(); - RevisionApi rApi = gApi.changes() + gApi.changes() .id("p~master~" + r.getChangeId()) - .current(); - rApi.review(approve()); - rApi.submit(); + .current() + .review(approve()); + gApi.changes() + .id("p~master~" + r.getChangeId()) + .current() + .submit(); } @Test @@ -123,6 +129,27 @@ public class RevisionIT extends AbstractDaemonTest { .delete(); } + @Test + public void cherryPick() throws GitAPIException, + IOException, RestApiException { + PushOneCommit.Result r = createChange(); + CherryPickInput in = new CherryPickInput(); + in.destination = "foo"; + in.message = "it goes to stable branch"; + gApi.projects() + .name(project.get()) + .branch(in.destination) + .create(new BranchInput()); + ChangeApi cApi = gApi.changes() + .id(r.getChangeId()) + .revision(r.getCommit().name()) + .cherryPick(in); + cApi.current() + .review(approve()); + cApi.current() + .submit(); + } + private PushOneCommit.Result createChange() throws GitAPIException, IOException { PushOneCommit push = new PushOneCommit(db, admin.getIdent()); diff --git a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/changes/CherryPickInput.java b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/changes/CherryPickInput.java new file mode 100644 index 0000000000..7ae7ef1b59 --- /dev/null +++ b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/changes/CherryPickInput.java @@ -0,0 +1,20 @@ +// Copyright (C) 2013 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.extensions.api.changes; + +public class CherryPickInput { + public String message; + public String destination; +} diff --git a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/changes/RevisionApi.java b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/changes/RevisionApi.java index ff4a94e501..c94ebcbd70 100644 --- a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/changes/RevisionApi.java +++ b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/changes/RevisionApi.java @@ -18,10 +18,11 @@ import com.google.gerrit.extensions.restapi.RestApiException; public interface RevisionApi { void delete() throws RestApiException; - void rebase() throws RestApiException; void review(ReviewInput in) throws RestApiException; /** {@code submit} with {@link SubmitInput#waitForMerge} set to true. */ void submit() throws RestApiException; void submit(SubmitInput in) throws RestApiException; + ChangeApi cherryPick(CherryPickInput in) throws RestApiException; + ChangeApi rebase() throws RestApiException; } diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/RevisionApiImpl.java b/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/RevisionApiImpl.java index 4e401c0d77..13013bd7d6 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/RevisionApiImpl.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/RevisionApiImpl.java @@ -15,10 +15,14 @@ package com.google.gerrit.server.api.changes; import com.google.gerrit.common.errors.EmailException; +import com.google.gerrit.extensions.api.changes.ChangeApi; +import com.google.gerrit.extensions.api.changes.Changes; +import com.google.gerrit.extensions.api.changes.CherryPickInput; import com.google.gerrit.extensions.api.changes.ReviewInput; import com.google.gerrit.extensions.api.changes.RevisionApi; import com.google.gerrit.extensions.api.changes.SubmitInput; import com.google.gerrit.extensions.restapi.RestApiException; +import com.google.gerrit.server.change.CherryPick; import com.google.gerrit.server.change.DeleteDraftPatchSet; import com.google.gerrit.server.change.PostReview; import com.google.gerrit.server.change.Rebase; @@ -36,6 +40,8 @@ class RevisionApiImpl implements RevisionApi { RevisionApiImpl create(RevisionResource r); } + private final Changes changes; + private final Provider cherryPick; private final Provider deleteDraft; private final Provider rebase; private final Provider review; @@ -43,11 +49,15 @@ class RevisionApiImpl implements RevisionApi { private final RevisionResource revision; @Inject - RevisionApiImpl(Provider deleteDraft, + RevisionApiImpl(Changes changes, + Provider cherryPick, + Provider deleteDraft, Provider rebase, Provider review, Provider submit, @Assisted RevisionResource r) { + this.changes = changes; + this.cherryPick = cherryPick; this.deleteDraft = deleteDraft; this.rebase = rebase; this.review = review; @@ -96,13 +106,26 @@ class RevisionApiImpl implements RevisionApi { } @Override - public void rebase() throws RestApiException { + public ChangeApi rebase() throws RestApiException { try { - rebase.get().apply(revision, null); + return changes.id(rebase.get().apply(revision, null)._number); } catch (OrmException e) { throw new RestApiException("Cannot rebase ps", e); } catch (EmailException e) { throw new RestApiException("Cannot rebase ps", e); } } + + @Override + public ChangeApi cherryPick(CherryPickInput in) throws RestApiException { + try { + return changes.id(cherryPick.get().apply(revision, in)._number); + } catch (OrmException e) { + throw new RestApiException("Cannot cherry pick", e); + } catch (EmailException e) { + throw new RestApiException("Cannot cherry pick", e); + } catch (IOException e) { + throw new RestApiException("Cannot cherry pick", e); + } + } } diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/CherryPick.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/CherryPick.java index ce0d33ea7c..fae8971be0 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/change/CherryPick.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/CherryPick.java @@ -15,6 +15,7 @@ package com.google.gerrit.server.change; import com.google.gerrit.common.errors.EmailException; +import com.google.gerrit.extensions.api.changes.CherryPickInput; import com.google.gerrit.extensions.restapi.AuthException; import com.google.gerrit.extensions.restapi.BadRequestException; import com.google.gerrit.extensions.restapi.ResourceConflictException; @@ -25,7 +26,6 @@ import com.google.gerrit.reviewdb.client.Change; import com.google.gerrit.reviewdb.client.PatchSet; import com.google.gerrit.reviewdb.server.ReviewDb; import com.google.gerrit.server.change.ChangeJson.ChangeInfo; -import com.google.gerrit.server.change.CherryPick.Input; import com.google.gerrit.server.git.MergeException; import com.google.gerrit.server.project.ChangeControl; import com.google.gerrit.server.project.InvalidChangeOperationException; @@ -37,17 +37,12 @@ import com.google.inject.Provider; import java.io.IOException; -class CherryPick implements RestModifyView, +public class CherryPick implements RestModifyView, UiAction { private final Provider dbProvider; private final Provider cherryPickChange; private final ChangeJson json; - static class Input { - String message; - String destination; - } - @Inject CherryPick(Provider dbProvider, Provider cherryPickChange, @@ -58,7 +53,7 @@ class CherryPick implements RestModifyView, } @Override - public ChangeInfo apply(RevisionResource revision, Input input) + public ChangeInfo apply(RevisionResource revision, CherryPickInput input) throws AuthException, BadRequestException, ResourceConflictException, ResourceNotFoundException, OrmException, IOException, EmailException { final ChangeControl control = revision.getControl();