Button to allow Cherry Picking of a change to another branch.
Built on the cherry pick REST Api.
Change-Id: I1b0211896eada7de12170ac73de60828bcf19d47
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/ChangeDetail.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/ChangeDetail.java
index 7ac21db..614be13 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/ChangeDetail.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/ChangeDetail.java
@@ -27,6 +27,7 @@
protected boolean allowsAnonymous;
protected boolean canAbandon;
protected boolean canEditCommitMessage;
+ protected boolean canCherryPick;
protected boolean canPublish;
protected boolean canRebase;
protected boolean canRestore;
@@ -82,6 +83,14 @@
canEditCommitMessage = a;
}
+ public boolean canCherryPick() {
+ return canCherryPick;
+ }
+
+ public void setCanCherryPick(final boolean a) {
+ canCherryPick = a;
+ }
+
public boolean canPublish() {
return canPublish;
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeApi.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeApi.java
index abd94c9..9375e44 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeApi.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeApi.java
@@ -82,6 +82,14 @@
}
/** Submit a specific revision of a change. */
+ public static void cherrypick(int id, String commit, String destination, String message, AsyncCallback<ChangeInfo> cb) {
+ CherryPickInput cherryPickInput = CherryPickInput.create();
+ cherryPickInput.setMessage(message);
+ cherryPickInput.setDestination(destination);
+ call(id, commit, "cherrypick").post(cherryPickInput, cb);
+ }
+
+ /** Submit a specific revision of a change. */
public static void submit(int id, String commit, AsyncCallback<SubmitInfo> cb) {
SubmitInput in = SubmitInput.create();
in.wait_for_merge(true);
@@ -100,6 +108,17 @@
}
}
+ private static class CherryPickInput extends JavaScriptObject {
+ static CherryPickInput create() {
+ return (CherryPickInput) createObject();
+ }
+ final native void setDestination(String d) /*-{ this.destination = d; }-*/;
+ final native void setMessage(String m) /*-{ this.message = m; }-*/;
+
+ protected CherryPickInput() {
+ }
+ };
+
private static class SubmitInput extends JavaScriptObject {
final native void wait_for_merge(boolean b) /*-{ this.wait_for_merge=b; }-*/;
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeConstants.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeConstants.java
index 62d85c4..421cb66 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeConstants.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeConstants.java
@@ -136,6 +136,12 @@
String editCommitMessageToolTip();
String titleEditCommitMessage();
+ String buttonCherryPickChangeBegin();
+ String buttonCherryPickChangeSend();
+ String headingCherryPickBranch();
+ String cherryPickCommitMessage();
+ String cherryPickTitle();
+
String buttonAbandonChangeBegin();
String buttonAbandonChangeSend();
String headingAbandonMessage();
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeConstants.properties b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeConstants.properties
index 9388c13..8dbdfa8 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeConstants.properties
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeConstants.properties
@@ -121,6 +121,12 @@
editCommitMessageToolTip = Edit Commit Message
titleEditCommitMessage = Create New Patch Set
+buttonCherryPickChangeBegin = Cherry Pick To
+buttonCherryPickChangeSend = Cherry Pick Change
+headingCherryPickBranch = Cherry Pick to Branch:
+cherryPickCommitMessage = Cherry Pick Commit Message:
+cherryPickTitle = Code Review - Cherry Pick Change to Another Branch
+
buttonRestoreChangeBegin = Restore Change
restoreChangeTitle = Code Review - Restore Change
headingRestoreMessage = Restore Message:
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeMessages.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeMessages.java
index 098fe07..742454e 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeMessages.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeMessages.java
@@ -24,6 +24,7 @@
String revertChangeDefaultMessage(String commitMsg, String commitId);
+ String cherryPickedChangeDefaultMessage(String commitMsg, String commitId);
String changeScreenTitleId(String changeId);
String outdatedHeader(int outdated);
String patchSetHeader(int id);
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeMessages.properties b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeMessages.properties
index 6c99081..f55c545 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeMessages.properties
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeMessages.properties
@@ -6,6 +6,7 @@
changesAbandonedInProject = Abandoned Changes In {0}
revertChangeDefaultMessage = Revert \"{0}\"\n\nThis reverts commit {1}
+cherryPickedChangeDefaultMessage = {0}\n(cherry picked from commit {1})
changeScreenTitleId = Change {0}
outdatedHeader = Change depends on {0} outdated change(s) and should be rebased on the latest patch sets.
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/PatchSetComplexDisclosurePanel.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/PatchSetComplexDisclosurePanel.java
index 2ed094d..679b6bf 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/PatchSetComplexDisclosurePanel.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/PatchSetComplexDisclosurePanel.java
@@ -25,6 +25,7 @@
import com.google.gerrit.client.ui.CommentedActionDialog;
import com.google.gerrit.client.ui.ComplexDisclosurePanel;
import com.google.gerrit.client.ui.ListenableAccountDiffPreference;
+import com.google.gerrit.client.ui.SmallHeading;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.common.data.ChangeDetail;
import com.google.gerrit.common.data.PatchSetDetail;
@@ -48,6 +49,7 @@
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
import com.google.gwt.user.client.ui.InlineLabel;
import com.google.gwt.user.client.ui.Panel;
+import com.google.gwt.user.client.ui.TextBox;
import com.google.gwtjsonrpc.common.VoidResult;
import java.util.HashSet;
@@ -379,6 +381,48 @@
actionsPanel.add(b);
}
+ if (changeDetail.canCherryPick()) {
+ final Button b = new Button(Util.C.buttonCherryPickChangeBegin());
+ b.addClickHandler(new ClickHandler() {
+ @Override
+ public void onClick(final ClickEvent event) {
+ b.setEnabled(false);
+ new CherryPickDialog(b) {
+ {
+ sendButton.setText(Util.C.buttonCherryPickChangeSend());
+ message.setText(Util.M.cherryPickedChangeDefaultMessage(
+ detail.getInfo().getMessage().trim(),
+ detail.getPatchSet().getRevision().get()));
+ }
+
+ @Override
+ public void onSend() {
+ ChangeApi.cherrypick(changeDetail.getChange().getChangeId(),
+ patchSet.getRevision().get(),
+ getDestinationBranch(),
+ getMessageText(),
+ new GerritCallback<ChangeInfo>() {
+ @Override
+ public void onSuccess(ChangeInfo result) {
+ sent = true;
+ Gerrit.display(PageLinks.toChange(new Change.Id(result
+ ._number())));
+ hide();
+ }
+
+ @Override
+ public void onFailure(Throwable caught) {
+ enableButtons(true);
+ super.onFailure(caught);
+ }
+ });
+ }
+ }.center();
+ }
+ });
+ actionsPanel.add(b);
+ }
+
if (changeDetail.canAbandon()) {
final Button b = new Button(Util.C.buttonAbandonChangeBegin());
b.addClickHandler(new ClickHandler() {
@@ -650,4 +694,23 @@
});
}
}
+
+ private abstract class CherryPickDialog extends ActionDialog {
+ private TextBox newBranch;
+
+ CherryPickDialog(final FocusWidget enableOnFailure) {
+ super(enableOnFailure, true, Util.C.cherryPickTitle(), Util.C.cherryPickCommitMessage());
+
+ newBranch = new TextBox();
+ newBranch.setVisibleLength(65);
+ setFocusOn(newBranch);
+ message.setCharacterWidth(70);
+ panel.insert(newBranch, 0);
+ panel.insert(new SmallHeading(Util.C.headingCherryPickBranch()), 0);
+ }
+
+ public String getDestinationBranch() {
+ return newBranch.getText();
+ }
+ }
}
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/changedetail/ChangeDetailFactory.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/changedetail/ChangeDetailFactory.java
index 08bcf88..aeaa3bb 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/changedetail/ChangeDetailFactory.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/rpc/changedetail/ChangeDetailFactory.java
@@ -14,6 +14,7 @@
package com.google.gerrit.httpd.rpc.changedetail;
+import com.google.gerrit.common.data.Capable;
import com.google.gerrit.common.data.ChangeDetail;
import com.google.gerrit.common.data.ChangeInfo;
import com.google.gerrit.common.data.SubmitRecord;
@@ -136,6 +137,8 @@
detail.setCanRevert(change.getStatus() == Change.Status.MERGED && control.canAddPatchSet());
+ detail.setCanCherryPick(control.getProjectControl().canPushToAtLeastOneRef() == Capable.OK);
+
detail.setCanEdit(control.getRefControl().canWrite());
detail.setCanEditCommitMessage(change.getStatus().isOpen() && control.canAddPatchSet());
detail.setCanEditTopicName(control.canEditTopicName());