Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobin Stocker2013-09-01 18:54:14 +0000
committerMatthias Sohn2013-09-18 19:46:05 +0000
commit47cb869505e1134e196b843a68ebb6f4a19cefa0 (patch)
tree170d81ddd19cd375a5ea8d9738b4bda2eb558109 /org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal
parent6e0d292c2840c19eaa4110f960eda689fe170414 (diff)
downloadegit-47cb869505e1134e196b843a68ebb6f4a19cefa0.tar.gz
egit-47cb869505e1134e196b843a68ebb6f4a19cefa0.tar.xz
egit-47cb869505e1134e196b843a68ebb6f4a19cefa0.zip
Offer to create branch when checking out remote-tracking branch
A common mistake for new users of EGit is that they want to work on a branch existing on a remote and therefore check out the remote-tracking branch. Instead the right thing to do would have been to create a new local branch based on it. This change shows a question whether to create a new local branch or whether to check out the commit behind the remote-tracking branch. To make it clear that there will be a question, the label is "Checkout..." instead of "Checkout" when a remote-tracking branch is selected. For advanced users already knowing about this, the question dialog is not shown when the warning about "detached HEAD" is disabled. Bug: 341679 Change-Id: I8701aee4bb12de0848f4820a3f7725435cbf106d Signed-off-by: Robin Stocker <robin@nibor.org>
Diffstat (limited to 'org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal')
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIText.java23
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/BranchOperationUI.java107
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/BranchResultDialog.java5
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CheckoutDialog.java14
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/CheckoutCommand.java27
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties11
6 files changed, 169 insertions, 18 deletions
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIText.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIText.java
index affce591f9..c8deef0e8d 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIText.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIText.java
@@ -903,6 +903,12 @@ public class UIText extends NLS {
public static String ClearCredentialsCommand_clearingCredentialsFailed;
/** */
+ public static String CheckoutCommand_CheckoutLabel;
+
+ /** */
+ public static String CheckoutCommand_CheckoutLabelWithQuestion;
+
+ /** */
public static String CheckoutConflictDialog_conflictMessage;
/** */
@@ -912,6 +918,9 @@ public class UIText extends NLS {
public static String CheckoutDialog_OkCheckout;
/** */
+ public static String CheckoutDialog_OkCheckoutWithQuestion;
+
+ /** */
public static String CheckoutDialog_Title;
/** */
@@ -2667,6 +2676,18 @@ public class UIText extends NLS {
public static String BranchConfigurationDialog_UpstreamBranchLabel;
/** */
+ public static String BranchOperationUI_CheckoutRemoteTrackingAsLocal;
+
+ /** */
+ public static String BranchOperationUI_CheckoutRemoteTrackingCommit;
+
+ /** */
+ public static String BranchOperationUI_CheckoutRemoteTrackingQuestion;
+
+ /** */
+ public static String BranchOperationUI_CheckoutRemoteTrackingTitle;
+
+ /** */
public static String BranchOperationUI_DetachedHeadTitle;
/** */
@@ -2721,7 +2742,7 @@ public class UIText extends NLS {
public static String BranchResultDialog_CheckoutConflictsTitle;
/** */
- public static String BranchResultDialog_dontShowAgain;
+ public static String BranchResultDialog_DetachedHeadWarningDontShowAgain;
/** */
public static String CheckoutDialog_ErrorCouldNotCreateNewRef;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/BranchOperationUI.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/BranchOperationUI.java
index c7c385ac6f..6e1313a9f1 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/BranchOperationUI.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/BranchOperationUI.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2010 SAP AG.
+ * Copyright (c) 2010, 2013 SAP AG and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -33,9 +33,11 @@ import org.eclipse.egit.ui.internal.dialogs.CheckoutDialog;
import org.eclipse.egit.ui.internal.dialogs.DeleteBranchDialog;
import org.eclipse.egit.ui.internal.dialogs.RenameBranchDialog;
import org.eclipse.egit.ui.internal.repository.CreateBranchWizard;
+import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.osgi.util.NLS;
@@ -60,6 +62,14 @@ public class BranchOperationUI {
private String target;
+ /**
+ * In the case of checkout conflicts, a dialog is shown to let the user
+ * stash, reset or commit. After that, checkout is tried again. The second
+ * time we do checkout, we don't want to ask any questions we already asked
+ * the first time, so this will be false then.
+ */
+ private final boolean showQuestionAboutTarget;
+
private final int mode;
/**
@@ -113,16 +123,43 @@ public class BranchOperationUI {
*/
public static BranchOperationUI checkout(Repository repository,
String target) {
- return new BranchOperationUI(repository, target);
+ return new BranchOperationUI(repository, target, true);
+ }
+
+ /**
+ * Create an operation for checking out a branch without showing a question
+ * dialog about the target.
+ *
+ * @param repository
+ * @param target
+ * a valid {@link Ref} name or commit id
+ * @return the {@link BranchOperationUI}
+ */
+ public static BranchOperationUI checkoutWithoutQuestion(
+ Repository repository, String target) {
+ return new BranchOperationUI(repository, target, false);
+ }
+
+ /**
+ * @param refName
+ * the full ref name which will be checked out
+ * @return true if checkout will need additional input from the user before
+ * continuing
+ */
+ public static boolean checkoutWillShowQuestionDialog(String refName) {
+ return shouldShowCheckoutRemoteTrackingDialog(refName);
}
/**
* @param repository
* @param target
+ * @param showQuestionAboutTarget
*/
- private BranchOperationUI(Repository repository, String target) {
+ private BranchOperationUI(Repository repository, String target,
+ boolean showQuestionAboutTarget) {
this.repository = repository;
this.target = target;
+ this.showQuestionAboutTarget = showQuestionAboutTarget;
this.mode = 0;
}
@@ -135,6 +172,7 @@ public class BranchOperationUI {
private BranchOperationUI(Repository repository, int mode) {
this.repository = repository;
this.mode = mode;
+ this.showQuestionAboutTarget = true;
}
/**
@@ -148,8 +186,8 @@ public class BranchOperationUI {
.getRepositoryState().getDescription()));
return;
}
- if (target == null)
- target = getTargetWithDialog();
+
+ askForTargetIfNecessary();
if (target == null)
return;
@@ -249,8 +287,8 @@ public class BranchOperationUI {
});
return;
}
- if (target == null)
- target = getTargetWithDialog();
+
+ askForTargetIfNecessary();
if (target == null)
return;
@@ -260,6 +298,32 @@ public class BranchOperationUI {
BranchResultDialog.show(bop.getResult(), repository, target);
}
+ private void askForTargetIfNecessary() {
+ if (target == null)
+ target = getTargetWithDialog();
+ if (target != null && showQuestionAboutTarget) {
+ if (shouldShowCheckoutRemoteTrackingDialog(target))
+ target = getTargetWithCheckoutRemoteTrackingDialog();
+ }
+ }
+
+ private static boolean shouldShowCheckoutRemoteTrackingDialog(String refName) {
+ boolean isRemoteTrackingBranch = refName != null
+ && refName.startsWith(Constants.R_REMOTES);
+ if (isRemoteTrackingBranch) {
+ boolean showDetachedHeadWarning = Activator.getDefault()
+ .getPreferenceStore()
+ .getBoolean(UIPreferences.SHOW_DETACHED_HEAD_WARNING);
+ // If the user has not yet chosen to ignore the warning about
+ // getting into a "detached HEAD" state, then we show them a dialog
+ // whether a remote-tracking branch should be checked out with a
+ // detached HEAD or checking it out as a new local branch.
+ return showDetachedHeadWarning;
+ } else {
+ return false;
+ }
+ }
+
private String getTargetWithDialog() {
AbstractBranchSelectionDialog dialog;
switch (mode) {
@@ -291,6 +355,35 @@ public class BranchOperationUI {
return dialog.getRefName();
}
+ private String getTargetWithCheckoutRemoteTrackingDialog() {
+ String[] buttons = new String[] {
+ UIText.BranchOperationUI_CheckoutRemoteTrackingAsLocal,
+ UIText.BranchOperationUI_CheckoutRemoteTrackingCommit,
+ IDialogConstants.CANCEL_LABEL };
+ MessageDialog questionDialog = new MessageDialog(
+ getShell(),
+ UIText.BranchOperationUI_CheckoutRemoteTrackingTitle,
+ null,
+ UIText.BranchOperationUI_CheckoutRemoteTrackingQuestion,
+ MessageDialog.QUESTION, buttons, 0);
+ int result = questionDialog.open();
+ if (result == 0) {
+ // Check out as new local branch
+ CreateBranchWizard wizard = new CreateBranchWizard(repository,
+ target);
+ WizardDialog createBranchDialog = new WizardDialog(getShell(),
+ wizard);
+ createBranchDialog.open();
+ return null;
+ } else if (result == 1) {
+ // Check out commit
+ return target;
+ } else {
+ // Cancel
+ return null;
+ }
+ }
+
private Shell getShell() {
return PlatformUI.getWorkbench().getDisplay().getActiveShell();
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/BranchResultDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/BranchResultDialog.java
index 76a20fc81e..d27dad0d49 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/BranchResultDialog.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/BranchResultDialog.java
@@ -161,7 +161,8 @@ public class BranchResultDialog extends MessageDialog {
}
if (shouldCheckout) {
super.buttonPressed(buttonId);
- BranchOperationUI op = BranchOperationUI.checkout(repository, target);
+ BranchOperationUI op = BranchOperationUI.checkoutWithoutQuestion(
+ repository, target);
op.start();
}
}
@@ -186,7 +187,7 @@ public class BranchResultDialog extends MessageDialog {
.getPreferenceStore();
if (store.getBoolean(UIPreferences.SHOW_DETACHED_HEAD_WARNING)) {
- String toggleMessage = UIText.BranchResultDialog_dontShowAgain;
+ String toggleMessage = UIText.BranchResultDialog_DetachedHeadWarningDontShowAgain;
MessageDialogWithToggle.openInformation(PlatformUI
.getWorkbench().getActiveWorkbenchWindow()
.getShell(),
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CheckoutDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CheckoutDialog.java
index 1ee44a8ea3..8ec2e715d3 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CheckoutDialog.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CheckoutDialog.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011 SAP AG.
+ * Copyright (c) 2011, 2013 SAP AG and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -20,6 +20,7 @@ import org.eclipse.egit.ui.Activator;
import org.eclipse.egit.ui.internal.CommonUtils;
import org.eclipse.egit.ui.internal.UIText;
import org.eclipse.egit.ui.internal.ValidationUtils;
+import org.eclipse.egit.ui.internal.branch.BranchOperationUI;
import org.eclipse.egit.ui.internal.repository.CreateBranchWizard;
import org.eclipse.egit.ui.internal.repository.tree.RefNode;
import org.eclipse.jface.dialogs.InputDialog;
@@ -95,6 +96,7 @@ public class CheckoutDialog extends AbstractBranchSelectionDialog {
.startsWith(Constants.R_REMOTES));
// handle multiple selection
+ Button okButton = getButton(Window.OK);
if (((TreeSelection) branchTree.getSelection()).size() > 1) {
TreeSelection selection = (TreeSelection) branchTree
.getSelection();
@@ -105,7 +107,7 @@ public class CheckoutDialog extends AbstractBranchSelectionDialog {
renameButton.setEnabled(false);
newButton.setEnabled(false);
} else {
- getButton(Window.OK).setEnabled(branchSelected || tagSelected);
+ okButton.setEnabled(branchSelected || tagSelected);
// we don't support rename on tags
renameButton.setEnabled(branchSelected && !tagSelected);
@@ -115,8 +117,12 @@ public class CheckoutDialog extends AbstractBranchSelectionDialog {
newButton.setEnabled(true);
}
- getButton(Window.OK).setEnabled(
- refName != null && !refName.equals(currentBranch));
+ if (BranchOperationUI.checkoutWillShowQuestionDialog(refName))
+ okButton.setText(UIText.CheckoutDialog_OkCheckoutWithQuestion);
+ else
+ okButton.setText(UIText.CheckoutDialog_OkCheckout);
+
+ okButton.setEnabled(refName != null && !refName.equals(currentBranch));
}
@Override
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/CheckoutCommand.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/CheckoutCommand.java
index 1ec55fe7a6..3b8ec7d46d 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/CheckoutCommand.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/CheckoutCommand.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2010 SAP AG.
+ * Copyright (c) 2010, 2013 SAP AG and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -10,18 +10,25 @@
*******************************************************************************/
package org.eclipse.egit.ui.internal.repository.tree.command;
+import java.util.List;
+import java.util.Map;
+
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.egit.ui.internal.UIText;
import org.eclipse.egit.ui.internal.branch.BranchOperationUI;
import org.eclipse.egit.ui.internal.repository.tree.RepositoryTreeNode;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
+import org.eclipse.ui.commands.IElementUpdater;
+import org.eclipse.ui.menus.UIElement;
/**
* Implements "Checkout"
*/
public class CheckoutCommand extends
- RepositoriesViewCommandHandler<RepositoryTreeNode> {
+ RepositoriesViewCommandHandler<RepositoryTreeNode> implements
+ IElementUpdater {
public Object execute(final ExecutionEvent event) throws ExecutionException {
final RepositoryTreeNode node = getSelectedNodes(event).get(0);
if (!(node.getObject() instanceof Ref))
@@ -35,4 +42,20 @@ public class CheckoutCommand extends
return null;
}
+
+ public void updateElement(UIElement element, Map parameters) {
+ List<RepositoryTreeNode> nodes = getSelectedNodes();
+ if (!nodes.isEmpty()) {
+ RepositoryTreeNode node = nodes.get(0);
+ if (node.getObject() instanceof Ref) {
+ Ref ref = (Ref) node.getObject();
+ if (BranchOperationUI.checkoutWillShowQuestionDialog(ref
+ .getName())) {
+ element.setText(UIText.CheckoutCommand_CheckoutLabelWithQuestion);
+ return;
+ }
+ }
+ }
+ element.setText(UIText.CheckoutCommand_CheckoutLabel);
+ }
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties
index 745e8b4322..7f83e62042 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties
@@ -234,9 +234,12 @@ CleanRepositoryPage_includeIgnored=Include ignored resources
CleanRepositoryPage_message=Select items to clean
CleanRepositoryPage_title=Clean Repository
ClearCredentialsCommand_clearingCredentialsFailed=Clearing credentials failed.
+CheckoutCommand_CheckoutLabel=&Checkout
+CheckoutCommand_CheckoutLabelWithQuestion=&Checkout...
CheckoutConflictDialog_conflictMessage=The files shown below have uncommitted changes which would be lost by the selected operation.\n\nEither commit the changes to the repository or discard the changes by resetting the current branch.
CheckoutDialog_Message=Select a ref and choose action to execute
CheckoutDialog_OkCheckout=&Checkout
+CheckoutDialog_OkCheckoutWithQuestion=&Checkout...
CheckoutDialog_Title=Checkout a ref or work with branches
CheckoutDialog_WindowTitle=Branches
CheckoutHandler_SelectBranchMessage=There is more than one branch for this commit. Please select the branch you want to check out.
@@ -912,6 +915,10 @@ BranchConfigurationDialog_RebaseLabel=&Rebase
BranchConfigurationDialog_RemoteLabel=Rem&ote:
BranchConfigurationDialog_SaveBranchConfigFailed=Could not save branch configuration
BranchConfigurationDialog_UpstreamBranchLabel=Upstream &Branch:
+BranchOperationUI_CheckoutRemoteTrackingAsLocal=Checkout as New Local Branch
+BranchOperationUI_CheckoutRemoteTrackingCommit=Checkout Commit
+BranchOperationUI_CheckoutRemoteTrackingQuestion=If you want to work on the branch, a new local branch has to be created and checked out.\n\nIf you just want to have a look at the state of the branch, the commit of the remote-tracking branch can be checked out.
+BranchOperationUI_CheckoutRemoteTrackingTitle=Check out remote-tracking branch
BranchOperationUI_DetachedHeadTitle=Detached HEAD
BranchOperationUI_DetachedHeadMessage=You are in the 'detached HEAD' state. This means that you don't have a local branch checked out.\n\nYou can look around, but it's not recommended to commit changes. The reason is that these commits would not be on any branch and would not be visible after checking out another branch.\n\nIf you want to make changes, create or checkout a local branch first.
BranchRenameDialog_Message=Please enter a new name for branch {0}
@@ -930,7 +937,7 @@ BranchResultDialog_buttonReset=Reset
BranchResultDialog_buttonStash=Stash...
BranchResultDialog_CheckoutConflictsMessage=The files shown below have uncommitted changes which would be lost by checking out ''{0}''.\n\nEither commit the changes, stash the changes, or discard the changes by resetting the current branch.
BranchResultDialog_CheckoutConflictsTitle=Checkout Conflicts
-BranchResultDialog_dontShowAgain=Don't show this confirmation dialog again
+BranchResultDialog_DetachedHeadWarningDontShowAgain=Don't show any dialogs about this again
CheckoutDialog_ErrorCouldNotCreateNewRef=Could not create new ref {0}
CheckoutDialog_ErrorCouldNotDeleteRef=Could not delete ref {0}
CheckoutDialog_ErrorCouldNotRenameRef=Failed to rename branch {0} -> {1}, status={2}
@@ -1062,7 +1069,7 @@ RepositoriesViewLabelProvider_SubmodulesNodeText=Submodules
RepositoriesViewLabelProvider_SymbolicRefNodeText=References
RepositoriesViewLabelProvider_TagsNodeText=Tags
-DialogsPreferencePage_DetachedHeadCombo=D&etached HEAD warning
+DialogsPreferencePage_DetachedHeadCombo=D&etached HEAD and checkout of remote-tracking branch
DialogsPreferencePage_HideConfirmationGroupHeader=Show confirmation dialogs
DialogsPreferencePage_HideWarningGroupHeader=Log warnings
DialogsPreferencePage_HomeDirWarning=&Home directory warning (Windows only)

Back to the top