--- a/git/nbproject/project.xml Tue Jul 01 16:57:50 2014 +0200
+++ a/git/nbproject/project.xml Tue Jul 01 17:18:16 2014 +0200
@@ -25,7 +25,7 @@
1
- 1.26
+ 1.27
--- a/git/src/org/netbeans/modules/git/client/GitClient.java Tue Jul 01 16:57:50 2014 +0200
+++ a/git/src/org/netbeans/modules/git/client/GitClient.java Tue Jul 01 17:18:16 2014 +0200
@@ -55,6 +55,8 @@
import java.util.logging.Logger;
import org.netbeans.libs.git.GitBlameResult;
import org.netbeans.libs.git.GitBranch;
+import org.netbeans.libs.git.GitCherryPickResult;
+import org.netbeans.libs.git.GitClient.CherryPickOperation;
import org.netbeans.libs.git.GitClient.DiffMode;
import org.netbeans.libs.git.GitClient.RebaseOperationType;
import org.netbeans.libs.git.GitClient.ResetType;
@@ -172,6 +174,7 @@
private static final HashSet NEED_REPOSITORY_REFRESH_COMMANDS = new HashSet(Arrays.asList("add",//NOI18N // may change state, e.g. MERGING->MERGED
"checkout", //NOI18N
"checkoutRevision", //NOI18N // current head changes
+ "cherryPick", //NOI18N
"commit", //NOI18N
"createBranch", //NOI18N // should refresh set of known branches
"createTag", //NOI18N - should refresh set of available tags
@@ -279,6 +282,16 @@
}, "checkoutRevision", new File[] { repositoryRoot }); //NOI18N
}
+ public GitCherryPickResult cherryPick (final CherryPickOperation op, final String[] revisions, final ProgressMonitor monitor) throws GitException.MissingObjectException, GitException {
+ return new CommandInvoker().runMethod(new Callable() {
+
+ @Override
+ public GitCherryPickResult call () throws Exception {
+ return delegate.cherryPick(op, revisions, monitor);
+ }
+ }, "cherryPick", new File[] { repositoryRoot }); //NOI18N
+ }
+
public void clean(final File[] roots, final ProgressMonitor monitor) throws GitException {
new CommandInvoker().runMethod(new Callable() {
--- a/git/src/org/netbeans/modules/git/ui/branch/Bundle.properties Tue Jul 01 16:57:50 2014 +0200
+++ a/git/src/org/netbeans/modules/git/ui/branch/Bundle.properties Tue Jul 01 17:18:16 2014 +0200
@@ -62,3 +62,4 @@
LBL_SetTrackingAction_PopupName=Set Tracked Branch...
SelectTrackedBranchPanel.errorLabel.text=jLabel1
+CherryPickPanel.jLabel1.text=Select revision to apply (cherry-pick) into HEAD
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ aaa074f13bd1 Tue Jul 01 17:18:16 2014 +0200
@@ -0,0 +1,188 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2010 Sun Microsystems, Inc.
+ */
+
+package org.netbeans.modules.git.ui.branch;
+
+import java.awt.Dialog;
+import java.awt.EventQueue;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.File;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.JButton;
+import org.netbeans.libs.git.GitBranch;
+import org.netbeans.libs.git.GitException;
+import org.netbeans.libs.git.GitRevisionInfo;
+import org.netbeans.libs.git.progress.ProgressMonitor;
+import org.netbeans.modules.git.Git;
+import org.netbeans.modules.git.client.GitClient;
+import org.netbeans.modules.git.ui.repository.RevisionDialogController;
+import org.netbeans.modules.git.utils.GitUtils;
+import org.openide.DialogDescriptor;
+import org.openide.DialogDisplayer;
+import org.openide.util.HelpCtx;
+import org.openide.util.NbBundle;
+import static org.netbeans.modules.git.ui.branch.Bundle.*;
+import org.netbeans.modules.git.ui.repository.RepositoryInfo;
+import org.netbeans.modules.versioning.util.Utils;
+import org.openide.util.Cancellable;
+import org.openide.util.RequestProcessor;
+
+/**
+ *
+ * @author ondra
+ */
+public class CherryPick {
+ private final CherryPickPanel panel;
+ private final RevisionDialogController revisionPicker;
+ private JButton okButton;
+ private DialogDescriptor dd;
+ private boolean valid;
+ private final File repository;
+ private final RequestProcessor.Task mergedIntoTask;
+ private String revision;
+
+ CherryPick (File repository, String initialRevision) {
+ this.repository = repository;
+ revisionPicker = new RevisionDialogController(repository, new File[] { repository }, initialRevision);
+ revisionPicker.setMergingInto(GitUtils.HEAD);
+ panel = new CherryPickPanel(revisionPicker.getPanel());
+ mergedIntoTask = Utils.createTask(new MergedIntoTask());
+ }
+
+ String getRevision() {
+ return revisionPicker.getRevision().getCommitId();
+ }
+
+ @NbBundle.Messages({
+ "LBL_CherryPick.OKButton.text=&Apply",
+ "# {0} - repository name", "LBL_CherryPick.title=Cherry Pick - {0}",
+ })
+ boolean showDialog () {
+ okButton = new JButton(LBL_CherryPick_OKButton_text());
+ org.openide.awt.Mnemonics.setLocalizedText(okButton, okButton.getText());
+ dd = new DialogDescriptor(panel, Bundle.LBL_CherryPick_title(repository), true,
+ new Object[] { okButton, DialogDescriptor.CANCEL_OPTION }, okButton, DialogDescriptor.DEFAULT_ALIGN,
+ new HelpCtx("org.netbeans.modules.git.ui.branch.CherryPick"), null); //NOI18N
+ enableRevisionPanel();
+ revisionPicker.addPropertyChangeListener(new PropertyChangeListener() {
+ @Override
+ public void propertyChange (PropertyChangeEvent evt) {
+ mergedIntoTask.cancel();
+ if (evt.getPropertyName() == RevisionDialogController.PROP_VALID) {
+ boolean v = Boolean.TRUE.equals(evt.getNewValue());
+ setValid(v);
+ if (v) {
+ revision = getRevision();
+ mergedIntoTask.schedule(500);
+ }
+ }
+ }
+ });
+ Dialog d = DialogDisplayer.getDefault().createDialog(dd);
+ d.setVisible(true);
+ return okButton == dd.getValue();
+ }
+
+ private void enableRevisionPanel () {
+ setValid(valid);
+ }
+
+ private void setValid (boolean flag) {
+ this.valid = flag;
+ okButton.setEnabled(flag);
+ dd.setValid(flag);
+ panel.lblError.setVisible(false);
+ }
+
+ @NbBundle.Messages({
+ "# {0} - branch name", "CherryPickPanel.info.merged=Already part of \"{0}\"!"
+ })
+ private class MergedIntoTask implements Runnable, Cancellable {
+
+ private ProgressMonitor.DefaultProgressMonitor pm;
+
+ @Override
+ public void run () {
+ pm = new ProgressMonitor.DefaultProgressMonitor();
+ final GitBranch activeBranch = RepositoryInfo.getInstance(repository).getActiveBranch();
+ boolean mergedInto = false;
+ final String rev = revision;
+ if (activeBranch.getId().equals(rev)) {
+ mergedInto = true;
+ } else {
+ GitClient client = null;
+ try {
+ client = Git.getInstance().getClient(repository);
+ GitRevisionInfo ancestor = client.getCommonAncestor(new String[] { revision, GitUtils.HEAD }, pm);
+ if (ancestor != null && ancestor.getRevision().equals(rev)) {
+ mergedInto = true;
+ }
+ } catch (GitException ex) {
+ Logger.getLogger(CherryPick.class.getName()).log(Level.FINE, null, ex);
+ } finally {
+ if (client != null) {
+ client.release();
+ }
+ }
+ }
+ final boolean merged = mergedInto;
+ EventQueue.invokeLater(new Runnable() {
+
+ @Override
+ public void run () {
+ if (rev.equals(revision) && merged) {
+ panel.lblError.setText(Bundle.CherryPickPanel_info_merged(activeBranch.getName()));
+ panel.lblError.setVisible(true);
+ }
+ }
+ });
+ }
+
+ @Override
+ public boolean cancel () {
+ return pm != null && pm.cancel();
+ }
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ aaa074f13bd1 Tue Jul 01 17:18:16 2014 +0200
@@ -0,0 +1,367 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2014 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2014 Sun Microsystems, Inc.
+ */
+
+package org.netbeans.modules.git.ui.branch;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.logging.Logger;
+import javax.swing.JButton;
+import org.netbeans.libs.git.GitCherryPickResult;
+import org.netbeans.libs.git.GitClient.CherryPickOperation;
+import org.netbeans.libs.git.GitException;
+import org.netbeans.libs.git.GitRepositoryState;
+import org.netbeans.libs.git.GitRevisionInfo;
+import org.netbeans.modules.git.Git;
+import org.netbeans.modules.git.client.GitClient;
+import org.netbeans.modules.git.client.GitClientExceptionHandler;
+import org.netbeans.modules.git.client.GitProgressSupport;
+import org.netbeans.modules.git.ui.actions.GitAction;
+import org.netbeans.modules.git.ui.actions.SingleRepositoryAction;
+import org.netbeans.modules.git.ui.commit.CommitAction;
+import org.netbeans.modules.git.ui.conflicts.ResolveConflictsExecutor;
+import org.netbeans.modules.git.ui.output.OutputLogger;
+import org.netbeans.modules.git.ui.repository.RepositoryInfo;
+import org.netbeans.modules.git.ui.status.StatusAction;
+import org.netbeans.modules.git.utils.GitUtils;
+import org.netbeans.modules.git.utils.ResultProcessor;
+import org.netbeans.modules.versioning.spi.VCSContext;
+import org.openide.DialogDisplayer;
+import org.openide.NotifyDescriptor;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionRegistration;
+import org.openide.awt.Mnemonics;
+import org.openide.nodes.AbstractNode;
+import org.openide.nodes.Children;
+import org.openide.nodes.Node;
+import org.openide.util.NbBundle;
+import org.openide.util.actions.SystemAction;
+import org.openide.util.lookup.Lookups;
+
+/**
+ *
+ * @author ondra
+ */
+@ActionID(id = "org.netbeans.modules.git.ui.branch.CherryPickAction", category = "Git")
+@ActionRegistration(displayName = "#LBL_CherryPickAction_Name", lazy = false)
+@NbBundle.Messages({
+ "LBL_CherryPickAction_Name=C&herry Pick...",
+ "LBL_CherryPickAction_PopupName=Cherry Pick...",
+ "CTL_CherryPickAction_continueButton_text=&Continue",
+ "CTL_CherryPickAction_continueButton_TTtext=Continue in cherry-picking scheduled commits.",
+ "CTL_CherryPickAction_abortButton_text=&Abort",
+ "CTL_CherryPickAction_abortButton_TTtext=Abort interrupted cherry-picking and rollback to the original commit.",
+ "CTL_CherryPickAction_quitButton_text=&Quit",
+ "CTL_CherryPickAction_quitButton_TTtext=Finish the currently cherry-picked commit but do not apply any other.",
+ "LBL_CherryPick_cherryPickingState_title=Unfinished Cherry-Pick",
+ "# {0} - repository name", "MSG_CherryPick_cherryPickingState_text=Repository {0} seems to be in the middle of an unfinished cherry-pick.\n\n"
+ + "You may continue with applying all scheduled commits\n"
+ + "or abort and rollback to the state before the cherry-pick started.",
+ "# {0} - repository name", "MSG_CherryPick_cherryPickingScheduledState_text=Repository {0} seems to be in the middle of an unfinished cherry-pick.\n\n"
+ + "You may continue with applying all scheduled commits,\n"
+ + "abort and rollback to the state before the cherry-pick started\n"
+ + "or quit the cherry-pick and leave the already applied commits.",
+ "# {0} - repository state", "MSG_CherryPickAction_notAllowed=Cherry picking not allowed in this state: \"{0}\"."
+})
+public class CherryPickAction extends SingleRepositoryAction {
+
+ private static final Logger LOG = Logger.getLogger(CherryPickAction.class.getName());
+
+ public void cherryPick (File repository, String preselectedRevision) {
+ RepositoryInfo info = RepositoryInfo.getInstance(repository);
+ info.refresh();
+ GitRepositoryState state = info.getRepositoryState();
+ boolean interrupted = isInterrupted(repository, state);
+ if (state == GitRepositoryState.SAFE && !interrupted) {
+ CherryPick cherryPick = new CherryPick(repository, preselectedRevision);
+ if (cherryPick.showDialog()) {
+ runCherryPick(repository, CherryPickOperation.BEGIN, new String[] { cherryPick.getRevision() });
+ }
+ } else if (interrupted) {
+ // abort or continue?
+ JButton btnContinue = new JButton();
+ Mnemonics.setLocalizedText(btnContinue, Bundle.CTL_CherryPickAction_continueButton_text());
+ btnContinue.setToolTipText(Bundle.CTL_CherryPickAction_continueButton_TTtext());
+ JButton btnAbort = new JButton();
+ Mnemonics.setLocalizedText(btnAbort, Bundle.CTL_CherryPickAction_abortButton_text());
+ btnAbort.setToolTipText(Bundle.CTL_CherryPickAction_abortButton_TTtext());
+ JButton btnQuit = new JButton();
+ Mnemonics.setLocalizedText(btnQuit, Bundle.CTL_CherryPickAction_quitButton_text());
+ btnQuit.setToolTipText(Bundle.CTL_CherryPickAction_quitButton_TTtext());
+ Map