summaryrefslogtreecommitdiff
path: root/plugins/hg4idea
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/hg4idea')
-rw-r--r--plugins/hg4idea/hg4idea.iml3
-rw-r--r--plugins/hg4idea/src/META-INF/plugin.xml1
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalAction.java29
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalSingleRepoAction.java47
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/action/HgActionUtil.java58
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchesAction.java2
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/action/HgCreateTagAction.java2
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/action/HgMerge.java2
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/action/HgProcessRebaseAction.java4
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/action/HgPullAction.java2
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/action/HgPushAction.java8
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/action/HgRunConflictResolverAction.java2
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/action/HgUpdateToAction.java2
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/command/HgIdentifyCommand.java2
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/command/HgOutgoingCommand.java27
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgCommandAuthenticator.java39
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgRemoteCommandExecutor.java26
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/log/HgHistoryUtil.java42
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/log/HgLogProvider.java12
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/provider/commit/HgCheckinEnvironment.java9
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/push/HgOutgoingCommitsProvider.java90
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPushOptionsPanel.java51
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPushSource.java38
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPushSupport.java109
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPusher.java (renamed from plugins/hg4idea/src/org/zmlx/hg4idea/HgPusher.java)95
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/push/HgTarget.java34
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/push/HgVcsPushOptionValue.java22
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java7
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/util/HgErrorUtil.java13
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java10
30 files changed, 663 insertions, 125 deletions
diff --git a/plugins/hg4idea/hg4idea.iml b/plugins/hg4idea/hg4idea.iml
index 7f5074895e4f..93b5a5109bde 100644
--- a/plugins/hg4idea/hg4idea.iml
+++ b/plugins/hg4idea/hg4idea.iml
@@ -16,9 +16,10 @@
<orderEntry type="module" module-name="vcs-impl" />
<orderEntry type="module" module-name="platform-impl" />
<orderEntry type="library" name="Guava" level="project" />
- <orderEntry type="module" module-name="dvcs" />
+ <orderEntry type="module" module-name="dvcs-impl" />
<orderEntry type="module" module-name="vcs-log-api" />
<orderEntry type="module" module-name="vcs-log-impl" />
+ <orderEntry type="module" module-name="dvcs-api" />
</component>
</module>
diff --git a/plugins/hg4idea/src/META-INF/plugin.xml b/plugins/hg4idea/src/META-INF/plugin.xml
index 9ccc175803f5..26b69326a703 100644
--- a/plugins/hg4idea/src/META-INF/plugin.xml
+++ b/plugins/hg4idea/src/META-INF/plugin.xml
@@ -21,6 +21,7 @@
<vcs name="hg4idea" vcsClass="org.zmlx.hg4idea.HgVcs" displayName="Mercurial" administrativeAreaName=".hg"/>
<checkoutProvider implementation="org.zmlx.hg4idea.provider.HgCheckoutProvider"/>
<vcsRootChecker implementation="org.zmlx.hg4idea.roots.HgRootChecker"/>
+ <pushSupport implementation="org.zmlx.hg4idea.push.HgPushSupport"/>
<errorHandler implementation="com.intellij.diagnostic.ITNReporter"/>
<vcsPopupProvider implementation="org.zmlx.hg4idea.provider.HgQuickListProvider"/>
<logProvider implementation="org.zmlx.hg4idea.log.HgLogProvider"/>
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalAction.java
index d38bc7bfc6a7..d6282ebe8786 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalAction.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalAction.java
@@ -29,7 +29,9 @@ import org.zmlx.hg4idea.util.HgUtil;
import javax.swing.*;
import java.lang.reflect.InvocationTargetException;
+import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
import java.util.List;
abstract class HgAbstractGlobalAction extends AnAction {
@@ -48,12 +50,17 @@ abstract class HgAbstractGlobalAction extends AnAction {
if (project == null) {
return;
}
- VirtualFile file = event.getData(CommonDataKeys.VIRTUAL_FILE);
- HgRepositoryManager repositoryManager = HgUtil.getRepositoryManager(project);
- HgRepository repo = file != null ? repositoryManager.getRepositoryForFile(file): HgUtil.getCurrentRepository(project);
+ VirtualFile[] files = event.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY);
+ final HgRepositoryManager repositoryManager = HgUtil.getRepositoryManager(project);
List<HgRepository> repositories = repositoryManager.getRepositories();
if (!repositories.isEmpty()) {
- execute(project, repositories, repo);
+ List<HgRepository> selectedRepositories = (files == null || files.length == 0)
+ ?
+ Collections.singletonList(HgUtil.getCurrentRepository(project))
+ : HgActionUtil.collectRepositoriesFromFiles(repositoryManager,
+ Arrays.asList(files));
+
+ execute(project, repositories, selectedRepositories);
}
}
@@ -66,7 +73,7 @@ abstract class HgAbstractGlobalAction extends AnAction {
protected abstract void execute(@NotNull Project project,
@NotNull Collection<HgRepository> repositories,
- @Nullable HgRepository selectedRepo);
+ @NotNull List<HgRepository> selectedRepositories);
public static void handleException(@Nullable Project project, @NotNull Exception e) {
handleException(project, "Error", e);
@@ -102,16 +109,4 @@ abstract class HgAbstractGlobalAction extends AnAction {
return true;
}
- @Nullable
- public static HgRepository getSelectedRepositoryFromEvent(AnActionEvent e) {
- final DataContext dataContext = e.getDataContext();
- final Project project = CommonDataKeys.PROJECT.getData(dataContext);
- if (project == null) {
- return null;
- }
- VirtualFile file = e.getData(CommonDataKeys.VIRTUAL_FILE);
- HgRepositoryManager repositoryManager = HgUtil.getRepositoryManager(project);
- return file != null ? repositoryManager.getRepositoryForFile(file) : HgUtil.getCurrentRepository(project);
- }
-
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalSingleRepoAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalSingleRepoAction.java
new file mode 100644
index 000000000000..bfb2d7715e68
--- /dev/null
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalSingleRepoAction.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * 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 org.zmlx.hg4idea.action;
+
+import com.intellij.openapi.project.Project;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.zmlx.hg4idea.repo.HgRepository;
+
+import javax.swing.*;
+import java.util.Collection;
+import java.util.List;
+
+public abstract class HgAbstractGlobalSingleRepoAction extends HgAbstractGlobalAction {
+
+ public HgAbstractGlobalSingleRepoAction(Icon icon) {
+ super(icon);
+ }
+
+ public HgAbstractGlobalSingleRepoAction() {
+ super();
+ }
+
+ @Override
+ protected void execute(@NotNull Project project,
+ @NotNull Collection<HgRepository> repositories,
+ @NotNull List<HgRepository> selectedRepositories) {
+ execute(project, repositories, selectedRepositories.isEmpty() ? null : selectedRepositories.get(0));
+ }
+
+ protected abstract void execute(@NotNull Project project,
+ @NotNull Collection<HgRepository> repositories,
+ @Nullable HgRepository selectedRepo);
+}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgActionUtil.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgActionUtil.java
new file mode 100644
index 000000000000..6abebd587787
--- /dev/null
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgActionUtil.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * 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 org.zmlx.hg4idea.action;
+
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
+import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
+import com.sun.istack.internal.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.zmlx.hg4idea.repo.HgRepository;
+import org.zmlx.hg4idea.repo.HgRepositoryManager;
+import org.zmlx.hg4idea.util.HgUtil;
+
+import java.util.Collection;
+import java.util.List;
+
+public class HgActionUtil {
+
+ @NotNull
+ public static List<HgRepository> collectRepositoriesFromFiles(@NotNull final HgRepositoryManager repositoryManager,
+ @NotNull Collection<VirtualFile> files) {
+ return ContainerUtil.mapNotNull(files, new Function<VirtualFile, HgRepository>() {
+ @Override
+ public HgRepository fun(VirtualFile file) {
+ return repositoryManager.getRepositoryForFile(file);
+ }
+ });
+ }
+
+ @Nullable
+ public static HgRepository getSelectedRepositoryFromEvent(AnActionEvent e) {
+ final DataContext dataContext = e.getDataContext();
+ final Project project = CommonDataKeys.PROJECT.getData(dataContext);
+ if (project == null) {
+ return null;
+ }
+ VirtualFile file = e.getData(CommonDataKeys.VIRTUAL_FILE);
+ HgRepositoryManager repositoryManager = HgUtil.getRepositoryManager(project);
+ return file != null ? repositoryManager.getRepositoryForFile(file) : HgUtil.getCurrentRepository(project);
+ }
+}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchesAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchesAction.java
index b8a10ed92116..d799cde1705c 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchesAction.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchesAction.java
@@ -22,7 +22,7 @@ import org.zmlx.hg4idea.repo.HgRepository;
import java.util.Collection;
-public class HgBranchesAction extends HgAbstractGlobalAction {
+public class HgBranchesAction extends HgAbstractGlobalSingleRepoAction {
@Override
protected void execute(@NotNull Project project, @NotNull Collection<HgRepository> repositories, @Nullable HgRepository selectedRepo) {
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgCreateTagAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgCreateTagAction.java
index 5c97e3ca9f39..c8734e8109f4 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgCreateTagAction.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgCreateTagAction.java
@@ -25,7 +25,7 @@ import org.zmlx.hg4idea.util.HgErrorUtil;
import java.util.Collection;
-public class HgCreateTagAction extends HgAbstractGlobalAction {
+public class HgCreateTagAction extends HgAbstractGlobalSingleRepoAction {
public void execute(@NotNull final Project project,
@NotNull Collection<HgRepository> repositories,
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgMerge.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgMerge.java
index 1743e7e5b56e..45ff24e382ce 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgMerge.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgMerge.java
@@ -33,7 +33,7 @@ import org.zmlx.hg4idea.ui.HgMergeDialog;
import java.util.Collection;
-public class HgMerge extends HgAbstractGlobalAction {
+public class HgMerge extends HgAbstractGlobalSingleRepoAction {
@Override
public void execute(@NotNull final Project project,
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgProcessRebaseAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgProcessRebaseAction.java
index 342369f0a9bb..84e9d5b1beaf 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgProcessRebaseAction.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgProcessRebaseAction.java
@@ -18,10 +18,10 @@ package org.zmlx.hg4idea.action;
import com.intellij.openapi.actionSystem.AnActionEvent;
import org.zmlx.hg4idea.repo.HgRepository;
-public abstract class HgProcessRebaseAction extends HgAbstractGlobalAction {
+public abstract class HgProcessRebaseAction extends HgAbstractGlobalSingleRepoAction {
protected static boolean isRebasing(AnActionEvent e) {
- HgRepository repository = HgAbstractGlobalAction.getSelectedRepositoryFromEvent(e);
+ HgRepository repository = HgActionUtil.getSelectedRepositoryFromEvent(e);
return repository != null && repository.getState() == HgRepository.State.REBASING;
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgPullAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgPullAction.java
index d5a934e1d86d..74beff13eb81 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgPullAction.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgPullAction.java
@@ -24,7 +24,7 @@ import org.zmlx.hg4idea.ui.HgPullDialog;
import java.util.Collection;
-public class HgPullAction extends HgAbstractGlobalAction {
+public class HgPullAction extends HgAbstractGlobalSingleRepoAction {
public HgPullAction() {
super(AllIcons.Actions.CheckOut);
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgPushAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgPushAction.java
index 1b5704f1d0f4..232b2ef7fa73 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgPushAction.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgPushAction.java
@@ -12,14 +12,14 @@
// limitations under the License.
package org.zmlx.hg4idea.action;
+import com.intellij.dvcs.push.ui.VcsPushDialog;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.zmlx.hg4idea.HgPusher;
import org.zmlx.hg4idea.repo.HgRepository;
import java.util.Collection;
+import java.util.List;
public class HgPushAction extends HgAbstractGlobalAction {
public HgPushAction() {
@@ -29,7 +29,7 @@ public class HgPushAction extends HgAbstractGlobalAction {
@Override
public void execute(@NotNull final Project project,
@NotNull Collection<HgRepository> repositories,
- @Nullable final HgRepository selectedRepo) {
- new HgPusher(project).showDialogAndPush(repositories, selectedRepo);
+ @NotNull final List<HgRepository> selectedRepositories) {
+ new VcsPushDialog(project, selectedRepositories).show();
}
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgRunConflictResolverAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgRunConflictResolverAction.java
index 938413e95356..279747c5278b 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgRunConflictResolverAction.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgRunConflictResolverAction.java
@@ -25,7 +25,7 @@ import org.zmlx.hg4idea.ui.HgRunConflictResolverDialog;
import java.util.Collection;
-public class HgRunConflictResolverAction extends HgAbstractGlobalAction {
+public class HgRunConflictResolverAction extends HgAbstractGlobalSingleRepoAction {
@Override
public void execute(@NotNull final Project project, @NotNull Collection<HgRepository> repositories, @Nullable HgRepository selectedRepo) {
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgUpdateToAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgUpdateToAction.java
index 7e1025921234..415cd223bd1f 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgUpdateToAction.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgUpdateToAction.java
@@ -29,7 +29,7 @@ import org.zmlx.hg4idea.util.HgErrorUtil;
import java.util.Collection;
-public class HgUpdateToAction extends HgAbstractGlobalAction {
+public class HgUpdateToAction extends HgAbstractGlobalSingleRepoAction {
@Override
protected void execute(@NotNull Project project, @NotNull Collection<HgRepository> repositories, @Nullable HgRepository selectedRepo) {
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgIdentifyCommand.java b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgIdentifyCommand.java
index c719d9174d39..4acbc1f72370 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgIdentifyCommand.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgIdentifyCommand.java
@@ -31,7 +31,7 @@ public class HgIdentifyCommand {
public HgCommandResult execute(@NotNull ModalityState state) {
final List<String> arguments = new LinkedList<String>();
arguments.add(source);
- final HgRemoteCommandExecutor executor = new HgRemoteCommandExecutor(project, source, state);
+ final HgRemoteCommandExecutor executor = new HgRemoteCommandExecutor(project, source, state, false);
executor.setSilent(true);
return executor.executeInCurrentThread(null, "identify", arguments);
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgOutgoingCommand.java b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgOutgoingCommand.java
index 64f155064ead..578af65a6b56 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgOutgoingCommand.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgOutgoingCommand.java
@@ -12,11 +12,19 @@
// limitations under the License.
package org.zmlx.hg4idea.command;
+import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.zmlx.hg4idea.execution.HgCommandResult;
+import org.zmlx.hg4idea.execution.HgRemoteCommandExecutor;
+import org.zmlx.hg4idea.log.HgHistoryUtil;
import org.zmlx.hg4idea.util.HgUtil;
+import java.util.LinkedList;
+import java.util.List;
+
public class HgOutgoingCommand extends HgRemoteChangesetsCommand {
public HgOutgoingCommand(Project project) {
@@ -27,4 +35,23 @@ public class HgOutgoingCommand extends HgRemoteChangesetsCommand {
protected String getRepositoryUrl(VirtualFile root) {
return HgUtil.getRepositoryDefaultPushPath(project, root);
}
+
+ @Nullable
+ public HgCommandResult execute(@NotNull VirtualFile repo,
+ @NotNull String template,
+ @NotNull String source,
+ @NotNull String destination,
+ boolean doNotShowAuthorizationRequest) {
+
+ List<String> arguments = new LinkedList<String>();
+ arguments.add("-n");
+ arguments.add("--template");
+ arguments.add(template);
+ arguments.add(HgHistoryUtil.prepareParameter("rev", source));
+ arguments.add(destination);
+ HgRemoteCommandExecutor commandExecutor =
+ new HgRemoteCommandExecutor(project, destination, ModalityState.any(), doNotShowAuthorizationRequest);
+ commandExecutor.setOutputAlwaysSuppressed(true);
+ return commandExecutor.executeInCurrentThread(repo, "outgoing", arguments);
+ }
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgCommandAuthenticator.java b/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgCommandAuthenticator.java
index 14f6c981777b..01f9083da808 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgCommandAuthenticator.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgCommandAuthenticator.java
@@ -39,10 +39,13 @@ class HgCommandAuthenticator {
private GetPasswordRunnable myGetPassword;
private final Project myProject;
private boolean myForceAuthorization;
+ //todo replace silent mode and/or force authorization
+ private boolean mySilentMode;
- public HgCommandAuthenticator(Project project, boolean forceAuthorization) {
+ public HgCommandAuthenticator(Project project, boolean forceAuthorization, boolean silent) {
myProject = project;
myForceAuthorization = forceAuthorization;
+ mySilentMode = silent;
}
public void saveCredentials() {
@@ -71,7 +74,7 @@ class HgCommandAuthenticator {
}
public boolean promptForAuthentication(Project project, String proposedLogin, String uri, String path, @Nullable ModalityState state) {
- GetPasswordRunnable runnable = new GetPasswordRunnable(project, proposedLogin, uri, path, myForceAuthorization);
+ GetPasswordRunnable runnable = new GetPasswordRunnable(project, proposedLogin, uri, path, myForceAuthorization, mySilentMode);
ApplicationManager.getApplication().invokeAndWait(runnable, state == null ? ModalityState.defaultModalityState() : state);
myGetPassword = runnable;
return runnable.isOk();
@@ -96,19 +99,27 @@ class HgCommandAuthenticator {
@Nullable private String myURL;
private boolean myRememberPassword;
private boolean myForceAuthorization;
+ private final boolean mySilent;
- public GetPasswordRunnable(Project project, String proposedLogin, String uri, String path, boolean forceAuthorization) {
+ public GetPasswordRunnable(Project project,
+ String proposedLogin,
+ String uri,
+ String path,
+ boolean forceAuthorization, boolean silent) {
this.myProject = project;
this.myProposedLogin = proposedLogin;
this.myURL = uri + path;
this.myForceAuthorization = forceAuthorization;
+ mySilent = silent;
}
-
+
public void run() {
// find if we've already been here
final HgVcs vcs = HgVcs.getInstance(myProject);
- if (vcs == null) { return; }
+ if (vcs == null) {
+ return;
+ }
@NotNull final HgGlobalSettings hgGlobalSettings = vcs.getGlobalSettings();
@Nullable String rememberedLoginsForUrl = null;
@@ -128,11 +139,14 @@ class HgCommandAuthenticator {
final String key = keyForUrlAndLogin(myURL, login);
try {
final PasswordSafeImpl passwordSafe = (PasswordSafeImpl)PasswordSafe.getInstance();
- password = passwordSafe.getMemoryProvider().getPassword(myProject, HgCommandAuthenticator.class, key);
- if (password == null) {
+ if (mySilent) {
+ password = passwordSafe.getMemoryProvider().getPassword(myProject, HgCommandAuthenticator.class, key);
+ }
+ else {
password = passwordSafe.getPassword(myProject, HgCommandAuthenticator.class, key);
}
- } catch (PasswordSafeException e) {
+ }
+ catch (PasswordSafeException e) {
LOG.info("Couldn't get password for key [" + key + "]", e);
}
}
@@ -146,7 +160,13 @@ class HgCommandAuthenticator {
return;
}
- final AuthDialog dialog = new AuthDialog(myProject, HgVcsMessages.message("hg4idea.dialog.login.password.required"), HgVcsMessages.message("hg4idea.dialog.login.description", myURL),
+ if (mySilent) {
+ ok = false;
+ return;
+ }
+
+ final AuthDialog dialog = new AuthDialog(myProject, HgVcsMessages.message("hg4idea.dialog.login.password.required"),
+ HgVcsMessages.message("hg4idea.dialog.login.description", myURL),
login, password, true);
dialog.show();
if (dialog.isOK()) {
@@ -182,5 +202,4 @@ class HgCommandAuthenticator {
private static String keyForUrlAndLogin(String stringUrl, String login) {
return login + ":" + stringUrl;
}
-
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgRemoteCommandExecutor.java b/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgRemoteCommandExecutor.java
index fdab67fbed6f..ce139cb16d9e 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgRemoteCommandExecutor.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgRemoteCommandExecutor.java
@@ -30,16 +30,22 @@ import java.util.List;
public class HgRemoteCommandExecutor extends HgCommandExecutor {
@Nullable private ModalityState myState;
+ final boolean myIgnoreAuthorizationRequest;
public HgRemoteCommandExecutor(@NotNull Project project, @Nullable String destination) {
- this(project, destination, null);
+ this(project, destination, null, false);
+ }
+
+ public HgRemoteCommandExecutor(@NotNull Project project, @Nullable String destination, boolean ignoreAuthorizationRequest) {
+ this(project, destination, null, ignoreAuthorizationRequest);
}
public HgRemoteCommandExecutor(@NotNull Project project,
@Nullable String destination,
- @Nullable ModalityState state) {
+ @Nullable ModalityState state, boolean ignoreAuthorizationRequest) {
super(project, destination);
myState = state;
+ myIgnoreAuthorizationRequest = ignoreAuthorizationRequest;
}
@Nullable
@@ -48,7 +54,7 @@ public class HgRemoteCommandExecutor extends HgCommandExecutor {
HgCommandResult result = executeInCurrentThread(repo, operation, arguments, false);
- if (HgErrorUtil.isAuthorizationError(result)) {
+ if (!myIgnoreAuthorizationRequest && HgErrorUtil.isAuthorizationError(result)) {
if (HgErrorUtil.hasAuthorizationInDestinationPath(myDestination)) {
new HgCommandResultNotifier(myProject)
.notifyError(result, "Authorization failed", "Your hgrc file settings have wrong username or password in [paths].\n" +
@@ -62,11 +68,11 @@ public class HgRemoteCommandExecutor extends HgCommandExecutor {
@Nullable
private HgCommandResult executeInCurrentThread(@Nullable final VirtualFile repo,
- @NotNull final String operation,
- @Nullable final List<String> arguments,
- boolean forceAuthorization) {
+ @NotNull final String operation,
+ @Nullable final List<String> arguments,
+ boolean forceAuthorization) {
- PassReceiver passReceiver = new PassReceiver(myProject, forceAuthorization, myState);
+ PassReceiver passReceiver = new PassReceiver(myProject, forceAuthorization, myIgnoreAuthorizationRequest, myState);
SocketServer passServer = new SocketServer(passReceiver);
try {
int passPort = passServer.start();
@@ -109,11 +115,13 @@ public class HgRemoteCommandExecutor extends HgCommandExecutor {
private final Project myProject;
private HgCommandAuthenticator myAuthenticator;
private boolean myForceAuthorization;
+ private boolean mySilentMode;
@Nullable private ModalityState myState;
- private PassReceiver(Project project, boolean forceAuthorization, @Nullable ModalityState state) {
+ private PassReceiver(Project project, boolean forceAuthorization, boolean silent, @Nullable ModalityState state) {
myProject = project;
myForceAuthorization = forceAuthorization;
+ mySilentMode = silent;
myState = state;
}
@@ -129,7 +137,7 @@ public class HgRemoteCommandExecutor extends HgCommandExecutor {
String path = new String(readDataBlock(dataInputStream));
String proposedLogin = new String(readDataBlock(dataInputStream));
- HgCommandAuthenticator authenticator = new HgCommandAuthenticator(myProject, myForceAuthorization);
+ HgCommandAuthenticator authenticator = new HgCommandAuthenticator(myProject, myForceAuthorization, mySilentMode);
boolean ok = authenticator.promptForAuthentication(myProject, proposedLogin, uri, path, myState);
if (ok) {
myAuthenticator = authenticator;
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgHistoryUtil.java b/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgHistoryUtil.java
index dfb576f98ab3..de565484e2d5 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgHistoryUtil.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgHistoryUtil.java
@@ -94,25 +94,35 @@ public class HgHistoryUtil {
}
/**
- * <p>Get & parse hg log detailed output with commits, their parents and their changes.</p>
+ * <p>Get & parse hg log detailed output with commits, their parents and their changes.
+ * For null destination return log command result</p>
* <p/>
* <p>Warning: this is method is efficient by speed, but don't query too much, because the whole log output is retrieved at once,
* and it can occupy too much memory. The estimate is ~600Kb for 1000 commits.</p>
*/
@NotNull
- public static List<? extends VcsFullCommitDetails> history(@NotNull final Project project, @NotNull final VirtualFile root, int limit,
+ public static List<? extends VcsFullCommitDetails> history(@NotNull final Project project,
+ @NotNull final VirtualFile root,
+ int limit,
@NotNull List<String> parameters) throws VcsException {
- final VcsLogObjectsFactory factory = getObjectsFactoryWithDisposeCheck(project);
- if (factory == null) {
- return Collections.emptyList();
- }
HgVcs hgvcs = HgVcs.getInstance(project);
assert hgvcs != null;
final HgVersion version = hgvcs.getVersion();
String[] templates = HgBaseLogParser.constructFullTemplateArgument(true, version);
HgCommandResult result = getLogResult(project, root, version, limit, parameters, HgChangesetUtil.makeTemplate(templates));
+ return createFullCommitsFromResult(project, root, result, version, false);
+ }
+
+ public static List<? extends VcsFullCommitDetails> createFullCommitsFromResult(@NotNull Project project,
+ @NotNull VirtualFile root,
+ @Nullable HgCommandResult result,
+ @NotNull HgVersion version, boolean silent) {
+ final VcsLogObjectsFactory factory = getObjectsFactoryWithDisposeCheck(project);
+ if (factory == null) {
+ return Collections.emptyList();
+ }
List<HgFileRevision> hgRevisions =
- getCommitRecords(project, result, new HgFileRevisionLogParser(project, getOriginalHgFile(project, root), version));
+ getCommitRecords(project, result, new HgFileRevisionLogParser(project, getOriginalHgFile(project, root), version), silent);
List<VcsFullCommitDetails> vcsFullCommitDetailsList = new ArrayList<VcsFullCommitDetails>();
for (HgFileRevision revision : hgRevisions) {
@@ -184,6 +194,13 @@ public class HgHistoryUtil {
public static <CommitInfo> List<CommitInfo> getCommitRecords(@NotNull Project project,
@Nullable HgCommandResult result,
@NotNull Function<String, CommitInfo> converter) {
+ return getCommitRecords(project, result, converter, false);
+ }
+
+ @NotNull
+ public static <CommitInfo> List<CommitInfo> getCommitRecords(@NotNull Project project,
+ @Nullable HgCommandResult result,
+ @NotNull Function<String, CommitInfo> converter, boolean silent) {
final List<CommitInfo> revisions = new LinkedList<CommitInfo>();
if (result == null) {
return revisions;
@@ -192,7 +209,12 @@ public class HgHistoryUtil {
List<String> errors = result.getErrorLines();
if (errors != null && !errors.isEmpty()) {
if (result.getExitValue() != 0) {
- VcsNotifier.getInstance(project).notifyError(HgVcsMessages.message("hg4idea.error.log.command.execution"), errors.toString());
+ if (silent) {
+ LOG.warn(errors.toString());
+ }
+ else {
+ VcsNotifier.getInstance(project).notifyError(HgVcsMessages.message("hg4idea.error.log.command.execution"), errors.toString());
+ }
return Collections.emptyList();
}
LOG.warn(errors.toString());
@@ -331,4 +353,8 @@ public class HgHistoryUtil {
}
return branchHeads;
}
+
+ public static String prepareParameter(String paramName, String value) {
+ return "--" + paramName + "=" + value; // no value escaping needed, because the parameter itself will be quoted by GeneralCommandLine
+ }
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgLogProvider.java b/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgLogProvider.java
index 4adec9dff515..3b989e448b61 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgLogProvider.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgLogProvider.java
@@ -180,11 +180,11 @@ public class HgLogProvider implements VcsLogProvider {
boolean atLeastOneBranchExists = false;
for (String branchName : filterCollection.getBranchFilter().getBranchNames()) {
if (branchName.equals(TIP_REFERENCE) || branchExists(repository, branchName)) {
- filterParameters.add(prepareParameter("branch", branchName));
+ filterParameters.add(HgHistoryUtil.prepareParameter("branch", branchName));
atLeastOneBranchExists = true;
}
else if (branchName.equals(HEAD_REFERENCE)) {
- filterParameters.add(prepareParameter("branch", "."));
+ filterParameters.add(HgHistoryUtil.prepareParameter("branch", "."));
filterParameters.add("-r");
filterParameters.add("::."); //all ancestors for current revision;
atLeastOneBranchExists = true;
@@ -197,7 +197,7 @@ public class HgLogProvider implements VcsLogProvider {
if (filterCollection.getUserFilter() != null) {
for (String authorName : filterCollection.getUserFilter().getUserNames(root)) {
- filterParameters.add(prepareParameter("user", authorName));
+ filterParameters.add(HgHistoryUtil.prepareParameter("user", authorName));
}
}
@@ -223,7 +223,7 @@ public class HgLogProvider implements VcsLogProvider {
if (filterCollection.getTextFilter() != null) {
String textFilter = filterCollection.getTextFilter().getText();
- filterParameters.add(prepareParameter("keyword", textFilter));
+ filterParameters.add(HgHistoryUtil.prepareParameter("keyword", textFilter));
}
if (filterCollection.getStructureFilter() != null) {
@@ -262,10 +262,6 @@ public class HgLogProvider implements VcsLogProvider {
return HgHistoryUtil.getDescendingHeadsOfBranches(myProject, root, commitHash);
}
- private static String prepareParameter(String paramName, String value) {
- return "--" + paramName + "=" + value; // no value escaping needed, because the parameter itself will be quoted by GeneralCommandLine
- }
-
private static boolean branchExists(@NotNull HgRepository repository, @NotNull String branchName) {
return repository.getBranches().keySet().contains(branchName) ||
HgUtil.getNamesWithoutHashes(repository.getBookmarks()).contains(branchName);
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/commit/HgCheckinEnvironment.java b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/commit/HgCheckinEnvironment.java
index c60e46c63ced..06b74148156e 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/commit/HgCheckinEnvironment.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/commit/HgCheckinEnvironment.java
@@ -13,6 +13,7 @@
package org.zmlx.hg4idea.provider.commit;
import com.intellij.dvcs.DvcsCommitAdditionalComponent;
+import com.intellij.dvcs.push.ui.VcsPushDialog;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.progress.ProgressIndicator;
@@ -37,6 +38,7 @@ import com.intellij.vcsUtil.VcsUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.*;
+import org.zmlx.hg4idea.action.HgActionUtil;
import org.zmlx.hg4idea.command.*;
import org.zmlx.hg4idea.execution.HgCommandException;
import org.zmlx.hg4idea.execution.HgCommandExecutor;
@@ -132,13 +134,12 @@ public class HgCheckinEnvironment implements CheckinEnvironment {
// push if needed
if (myNextCommitIsPushed && exceptions.isEmpty()) {
- final VirtualFile preselectedRepo = repositoriesMap.size() == 1 ? repositoriesMap.keySet().iterator().next() : null;
+ final Set<VirtualFile> preselectedFiles = repositoriesMap.keySet();
HgRepositoryManager repositoryManager = HgUtil.getRepositoryManager(myProject);
- final HgRepository repo = preselectedRepo != null ? repositoryManager.getRepositoryForFile(preselectedRepo) : null;
- final Collection<HgRepository> repositories = repositoryManager.getRepositories();
+ final List<HgRepository> preselectedRepositories = HgActionUtil.collectRepositoriesFromFiles(repositoryManager, preselectedFiles);
UIUtil.invokeLaterIfNeeded(new Runnable() {
public void run() {
- new HgPusher(myProject).showDialogAndPush(repositories, repo);
+ new VcsPushDialog(myProject, preselectedRepositories).show();
}
});
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgOutgoingCommitsProvider.java b/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgOutgoingCommitsProvider.java
new file mode 100644
index 000000000000..70055cafe1a1
--- /dev/null
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgOutgoingCommitsProvider.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * 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 org.zmlx.hg4idea.push;
+
+import com.intellij.dvcs.push.*;
+import com.intellij.dvcs.repo.Repository;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.vcs.log.VcsFullCommitDetails;
+import org.jetbrains.annotations.NotNull;
+import org.zmlx.hg4idea.HgVcs;
+import org.zmlx.hg4idea.command.HgOutgoingCommand;
+import org.zmlx.hg4idea.execution.HgCommandResult;
+import org.zmlx.hg4idea.log.HgBaseLogParser;
+import org.zmlx.hg4idea.log.HgHistoryUtil;
+import org.zmlx.hg4idea.util.HgChangesetUtil;
+import org.zmlx.hg4idea.util.HgErrorUtil;
+import org.zmlx.hg4idea.util.HgVersion;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class HgOutgoingCommitsProvider extends OutgoingCommitsProvider {
+
+
+ private static final Logger LOG = Logger.getInstance(HgOutgoingCommitsProvider.class);
+ private static final String LOGIN_AND_REFRESH_LINK = "Enter Password & Refresh";
+
+ @NotNull
+ @Override
+ public OutgoingResult getOutgoingCommits(@NotNull final Repository repository,
+ @NotNull final PushSpec pushSpec,
+ boolean initial) {
+ final Project project = repository.getProject();
+ HgVcs hgvcs = HgVcs.getInstance(project);
+ assert hgvcs != null;
+ final HgVersion version = hgvcs.getVersion();
+ String[] templates = HgBaseLogParser.constructFullTemplateArgument(true, version);
+ HgOutgoingCommand hgOutgoingCommand = new HgOutgoingCommand(project);
+ HgTarget hgTarget = (HgTarget)pushSpec.getTarget();
+ List<VcsError> errors = new ArrayList<VcsError>();
+ if (hgTarget == null || StringUtil.isEmptyOrSpaces(hgTarget.myTarget)) {
+ errors.add(new VcsError("Hg push path could not be empty."));
+ return new OutgoingResult(Collections.<VcsFullCommitDetails>emptyList(), errors);
+ }
+ HgCommandResult result = hgOutgoingCommand
+ .execute(repository.getRoot(), HgChangesetUtil.makeTemplate(templates), pushSpec.getSource().getPresentation(),
+ hgTarget.myTarget, initial);
+ if (result == null) {
+ errors.add(new VcsError("Couldn't execute hg outgoing command for " + repository));
+ return new OutgoingResult(Collections.<VcsFullCommitDetails>emptyList(), errors);
+ }
+ List<String> resultErrors = result.getErrorLines();
+ if (resultErrors != null && !resultErrors.isEmpty() && result.getExitValue() != 0) {
+ for (String error : resultErrors) {
+ if (HgErrorUtil.isAbortLine(error)) {
+ if (HgErrorUtil.isAuthorizationError(error)) {
+ VcsError authorizationError =
+ new VcsError(error + "<a href='authenticate'>" + LOGIN_AND_REFRESH_LINK + "</a>", new VcsErrorHandler() {
+ public void handleError(@NotNull CommitLoader commitLoader) {
+ commitLoader.reloadCommits();
+ }
+ });
+ errors.add(authorizationError);
+ }
+ else {
+ errors.add(new VcsError(error));
+ }
+ }
+ }
+ LOG.warn(resultErrors.toString());
+ }
+ return new OutgoingResult(HgHistoryUtil.createFullCommitsFromResult(project, repository.getRoot(), result, version, true), errors);
+ }
+}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPushOptionsPanel.java b/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPushOptionsPanel.java
new file mode 100644
index 000000000000..336f8ff1aa4c
--- /dev/null
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPushOptionsPanel.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * 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 org.zmlx.hg4idea.push;
+
+import com.intellij.dvcs.push.VcsPushOptionsPanel;
+import com.intellij.openapi.ui.ComboBox;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionListener;
+
+public class HgPushOptionsPanel extends VcsPushOptionsPanel {
+
+ private final ComboBox myReferenceStrategyCombobox;
+
+ public HgPushOptionsPanel() {
+ setLayout(new BorderLayout());
+ myReferenceStrategyCombobox = new ComboBox();
+ HgVcsPushOptionValue[] values = HgVcsPushOptionValue.values();
+ DefaultComboBoxModel comboModel = new DefaultComboBoxModel(values);
+ myReferenceStrategyCombobox.setModel(comboModel);
+ JLabel referenceStrategyLabel = new JLabel("Export Bookmarks: ");
+ add(referenceStrategyLabel, BorderLayout.WEST);
+ add(myReferenceStrategyCombobox, BorderLayout.CENTER);
+ }
+
+ @Override
+ @NotNull
+ public HgVcsPushOptionValue getValue() {
+ return (HgVcsPushOptionValue)myReferenceStrategyCombobox.getSelectedItem();
+ }
+
+ @Override
+ public void addValueChangeListener(ActionListener listener) {
+ myReferenceStrategyCombobox.addActionListener(listener);
+ }
+}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPushSource.java b/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPushSource.java
new file mode 100644
index 000000000000..babd49c9b31d
--- /dev/null
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPushSource.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * 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 org.zmlx.hg4idea.push;
+
+import com.intellij.dvcs.push.PushSource;
+import org.jetbrains.annotations.NotNull;
+
+public class HgPushSource implements PushSource {
+ @NotNull private String myBranch;
+
+ public HgPushSource(@NotNull String branch) {
+ myBranch = branch;
+ }
+
+ @NotNull
+ @Override
+ public String getPresentation() {
+ return myBranch;
+ }
+
+ @NotNull
+ public String getBranch() {
+ return myBranch; // presentation may differ from branch
+ }
+}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPushSupport.java b/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPushSupport.java
new file mode 100644
index 000000000000..4bfa134a5e26
--- /dev/null
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPushSupport.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * 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 org.zmlx.hg4idea.push;
+
+import com.intellij.dvcs.push.*;
+import com.intellij.dvcs.repo.Repository;
+import com.intellij.dvcs.repo.RepositoryManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vcs.AbstractVcs;
+import com.intellij.util.Function;
+import com.intellij.util.ObjectUtils;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.zmlx.hg4idea.HgVcs;
+import org.zmlx.hg4idea.repo.HgRepository;
+import org.zmlx.hg4idea.util.HgUtil;
+
+import java.util.Collection;
+
+public class HgPushSupport extends PushSupport<HgRepository> {
+
+ @NotNull private final Project myProject;
+ @NotNull private final HgVcs myVcs;
+
+ public HgPushSupport(@NotNull Project project) {
+ myProject = project;
+ myVcs = ObjectUtils.assertNotNull(HgVcs.getInstance(myProject));
+ }
+
+ @NotNull
+ @Override
+ public AbstractVcs getVcs() {
+ return myVcs;
+ }
+
+ @NotNull
+ @Override
+ public Pusher getPusher() {
+ return new HgPusher();
+ }
+
+ @NotNull
+ @Override
+ public OutgoingCommitsProvider getOutgoingCommitsProvider() {
+ return new HgOutgoingCommitsProvider();
+ }
+
+ @Nullable
+ @Override
+ public HgTarget getDefaultTarget(@NotNull HgRepository repository) {
+ String defaultPushPath = repository.getRepositoryConfig().getDefaultPushPath();
+ return defaultPushPath == null ? null : new HgTarget(defaultPushPath);
+ }
+
+ @NotNull
+ @Override
+ public Collection<String> getTargetNames(@NotNull HgRepository repository) {
+ return ContainerUtil.map(repository.getRepositoryConfig().getPaths(), new Function<String, String>() {
+ @Override
+ public String fun(String s) {
+ return HgUtil.removePasswordIfNeeded(s);
+ }
+ });
+ }
+
+ @NotNull
+ @Override
+ public HgPushSource getSource(@NotNull HgRepository repository) {
+ String localBranch = HgUtil.getActiveBranchName(repository);
+ return new HgPushSource(localBranch);
+ }
+
+ @Override
+ public HgTarget createTarget(@NotNull HgRepository repository, @NotNull String targetName) {
+ return new HgTarget(targetName);
+ }
+
+ @NotNull
+ @Override
+ public RepositoryManager<HgRepository> getRepositoryManager() {
+ return HgUtil.getRepositoryManager(myProject);
+ }
+
+ @Nullable
+ public VcsPushOptionsPanel getVcsPushOptionsPanel() {
+ return new HgPushOptionsPanel();
+ }
+
+ @Override
+ @Nullable
+ public VcsError validate(@NotNull Repository repository, @Nullable String targetToValidate) {
+ return StringUtil.isEmptyOrSpaces(targetToValidate) ? new VcsError("Please, specify remote push path for repository!") : null;
+ }
+}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/HgPusher.java b/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPusher.java
index 2b6108dddbbc..f019035a373f 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/HgPusher.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPusher.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,16 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.zmlx.hg4idea;
+package org.zmlx.hg4idea.push;
+import com.intellij.dvcs.push.PushSpec;
+import com.intellij.dvcs.push.Pusher;
+import com.intellij.dvcs.push.VcsPushOptionValue;
+import com.intellij.dvcs.repo.Repository;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.progress.ProgressIndicator;
-import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.VcsNotifier;
-import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -31,52 +31,54 @@ import org.zmlx.hg4idea.command.HgPushCommand;
import org.zmlx.hg4idea.execution.HgCommandResult;
import org.zmlx.hg4idea.execution.HgCommandResultHandler;
import org.zmlx.hg4idea.repo.HgRepository;
-import org.zmlx.hg4idea.ui.HgPushDialog;
-import java.util.Collection;
import java.util.List;
-import java.util.concurrent.atomic.AtomicReference;
+import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-public class HgPusher {
+public class HgPusher extends Pusher {
private static final Logger LOG = Logger.getInstance(HgPusher.class);
- private static Pattern PUSH_COMMITS_PATTERN = Pattern.compile(".*added (\\d+) changesets.*");
+ private static final String ONE = "one";
+ private static Pattern PUSH_COMMITS_PATTERN = Pattern.compile(".*(?:added|pushed) (\\d+|" + ONE + ") changeset.*");
// hg push command has definite exit values for some cases:
// mercurial returns 0 if push was successful, 1 if nothing to push. see hg push --help
private static int PUSH_SUCCEEDED_EXIT_VALUE = 0;
private static int NOTHING_TO_PUSH_EXIT_VALUE = 1;
- private final Project myProject;
-
- public HgPusher(Project project) {
- myProject = project;
- }
-
- public void showDialogAndPush (@NotNull Collection<HgRepository> repositories,@Nullable final HgRepository selectedRepo) {
-
- if (repositories.isEmpty()) {
- VcsBalloonProblemNotifier.showOverChangesView(myProject, "No Mercurial repositories in the project", MessageType.ERROR);
- return;
- }
- final AtomicReference<HgPushCommand> pushCommand = new AtomicReference<HgPushCommand>();
- final HgPushDialog dialog = new HgPushDialog(myProject, repositories, selectedRepo);
- dialog.show();
- if (dialog.isOK()) {
- pushCommand.set(preparePushCommand(myProject, dialog));
- new Task.Backgroundable(myProject, "Pushing...", false) {
- @Override
- public void run(@NotNull ProgressIndicator indicator) {
- if (pushCommand.get() != null) {
- push(myProject, pushCommand.get());
- }
+ @Override
+ public void push(@NotNull Map<Repository, PushSpec> pushSpecs, @Nullable VcsPushOptionValue vcsPushOptionValue, boolean force) {
+ for (Map.Entry<Repository, PushSpec> entry : pushSpecs.entrySet()) {
+ Repository repository = entry.getKey();
+ HgRepository hgRepository = (HgRepository)repository;
+ PushSpec hgSpec = entry.getValue();
+ HgTarget destination = (HgTarget)hgSpec.getTarget();
+ if (destination == null) {
+ continue;
+ }
+ HgPushSource source = (HgPushSource)hgSpec.getSource();
+ Project project = repository.getProject();
+ final HgPushCommand pushCommand = new HgPushCommand(project, repository.getRoot(), destination.myTarget);
+ pushCommand.setIsNewBranch(true); // set always true, because it just allow mercurial to create a new one if needed
+ pushCommand.setForce(force);
+ String branchName = source.getBranch();
+ if (branchName.equals(hgRepository.getCurrentBookmark())) {
+ if (vcsPushOptionValue == HgVcsPushOptionValue.Current) {
+ pushCommand.setBookmarkName(branchName);
+ }
+ else {
+ pushCommand.setRevision(branchName);
}
- }.queue();
+ }
+ else {
+ pushCommand.setBranchName(branchName);
+ }
+ push(project, pushCommand);
}
}
- private static void push(final Project project, HgPushCommand command) {
+ public static void push(@NotNull final Project project, @NotNull HgPushCommand command) {
final VirtualFile repo = command.getRepo();
command.execute(new HgCommandResultHandler() {
@Override
@@ -91,9 +93,11 @@ public class HgPusher {
String successDescription = String.format("Pushed %d %s [%s]", commitsNum, StringUtil.pluralize("commit", commitsNum),
repo.getPresentableName());
VcsNotifier.getInstance(project).notifySuccess(successTitle, successDescription);
- } else if (result.getExitValue() == NOTHING_TO_PUSH_EXIT_VALUE) {
+ }
+ else if (result.getExitValue() == NOTHING_TO_PUSH_EXIT_VALUE) {
VcsNotifier.getInstance(project).notifySuccess("Nothing to push");
- } else {
+ }
+ else {
new HgCommandResultNotifier(project).notifyError(result, "Push failed",
"Failed to push to [" + repo.getPresentableName() + "]");
}
@@ -101,17 +105,7 @@ public class HgPusher {
});
}
- private static HgPushCommand preparePushCommand(Project project, HgPushDialog dialog) {
- final HgPushCommand command = new HgPushCommand(project, dialog.getRepository().getRoot(), dialog.getTarget());
- command.setRevision(dialog.getRevision());
- command.setForce(dialog.isForce());
- command.setBranchName(dialog.getBranch());
- command.setBookmarkName(dialog.getBookmarkName());
- command.setIsNewBranch(dialog.isNewBranch());
- return command;
- }
-
- private static int getNumberOfPushedCommits(HgCommandResult result) {
+ private static int getNumberOfPushedCommits(@NotNull HgCommandResult result) {
int numberOfCommitsInAllSubrepos = 0;
final List<String> outputLines = result.getOutputLines();
for (String outputLine : outputLines) {
@@ -119,7 +113,8 @@ public class HgPusher {
final Matcher matcher = PUSH_COMMITS_PATTERN.matcher(outputLine);
if (matcher.matches()) {
try {
- numberOfCommitsInAllSubrepos += Integer.parseInt(matcher.group(1));
+ String numberOfCommits = matcher.group(1);
+ numberOfCommitsInAllSubrepos += ONE.equals(numberOfCommits) ? 1 : Integer.parseInt(numberOfCommits);
}
catch (NumberFormatException e) {
LOG.error("getNumberOfPushedCommits ", e);
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgTarget.java b/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgTarget.java
new file mode 100644
index 000000000000..8f5aca3838ca
--- /dev/null
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgTarget.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * 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 org.zmlx.hg4idea.push;
+
+import com.intellij.dvcs.push.PushTarget;
+import org.jetbrains.annotations.NotNull;
+import org.zmlx.hg4idea.util.HgUtil;
+
+public class HgTarget implements PushTarget {
+ @NotNull String myTarget;
+
+ public HgTarget(@NotNull String name) {
+ myTarget = name;
+ }
+
+ @Override
+ @NotNull
+ public String getPresentation() {
+ return HgUtil.removePasswordIfNeeded(myTarget);
+ }
+}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgVcsPushOptionValue.java b/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgVcsPushOptionValue.java
new file mode 100644
index 000000000000..5b35e7f5e6e0
--- /dev/null
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgVcsPushOptionValue.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * 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 org.zmlx.hg4idea.push;
+
+import com.intellij.dvcs.push.VcsPushOptionValue;
+
+public enum HgVcsPushOptionValue implements VcsPushOptionValue {
+ None, Current
+}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java
index 77c81ee80993..b670fb056c0c 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java
@@ -21,6 +21,7 @@ import com.intellij.openapi.Disposable;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.vcs.AbstractVcs;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.vcs.log.Hash;
@@ -96,6 +97,12 @@ public class HgRepositoryImpl extends RepositoryImpl implements HgRepository {
return myInfo.getState();
}
+ @Nullable
+ @Override
+ public AbstractVcs getVcs() {
+ return HgVcs.getInstance(getProject());
+ }
+
@Override
@NotNull
public String getCurrentBranch() {
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgErrorUtil.java b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgErrorUtil.java
index 1810370588b7..7592f5830ee5 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgErrorUtil.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgErrorUtil.java
@@ -43,7 +43,7 @@ public final class HgErrorUtil {
}
final List<String> errorLines = result.getErrorLines();
for (String line : errorLines) {
- if (!StringUtil.isEmptyOrSpaces(line) && line.trim().startsWith("abort:")) {
+ if (isAbortLine(line)) {
return true;
}
}
@@ -55,8 +55,7 @@ public final class HgErrorUtil {
return false;
}
String line = getLastErrorLine(result);
- return !StringUtil.isEmptyOrSpaces(line) && (line.contains("authorization required") || line.contains("authorization failed")
- );
+ return isAuthorizationError(line);
}
@Nullable
@@ -119,4 +118,12 @@ public final class HgErrorUtil {
Matcher matcher = UNCOMMITTED_PATTERN.matcher(result.getRawError());
return matcher.matches();
}
+
+ public static boolean isAuthorizationError(String line) {
+ return !StringUtil.isEmptyOrSpaces(line) && (line.contains("authorization required") || line.contains("authorization failed"));
+ }
+
+ public static boolean isAbortLine(String line) {
+ return !StringUtil.isEmptyOrSpaces(line) && line.trim().startsWith("abort:");
+ }
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java
index 1cc100efb029..3bb14721f0a8 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java
@@ -32,6 +32,7 @@ import com.intellij.openapi.vcs.*;
import com.intellij.openapi.vcs.changes.*;
import com.intellij.openapi.vcs.history.FileHistoryPanelImpl;
import com.intellij.openapi.vcs.history.VcsFileRevisionEx;
+import com.intellij.openapi.vcs.vfs.AbstractVcsVirtualFile;
import com.intellij.openapi.vcs.vfs.VcsVirtualFile;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.openapi.vfs.LocalFileSystem;
@@ -474,7 +475,7 @@ public abstract class HgUtil {
*/
@Nullable
public static VirtualFile convertToLocalVirtualFile(@Nullable VirtualFile file) {
- if (!(file instanceof VcsVirtualFile)) {
+ if (!(file instanceof AbstractVcsVirtualFile)) {
return file;
}
LocalFileSystem lfs = LocalFileSystem.getInstance();
@@ -583,11 +584,16 @@ public abstract class HgUtil {
if (state != HgRepository.State.NORMAL) {
branchText += state.toString() + " ";
}
+ return branchText + getActiveBranchName(repository);
+ }
+
+ @NotNull
+ public static String getActiveBranchName(@NotNull HgRepository repository) {
String branchOrBookMarkName = repository.getCurrentBookmark();
if (StringUtil.isEmptyOrSpaces(branchOrBookMarkName)) {
branchOrBookMarkName = repository.getCurrentBranch();
}
- return branchText + branchOrBookMarkName;
+ return branchOrBookMarkName;
}
@NotNull