summaryrefslogtreecommitdiff
path: root/plugins/hg4idea/src/org
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/hg4idea/src/org')
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/HgProjectSettings.java15
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalAction.java2
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopup.java127
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/action/HgCommonBranchActions.java133
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchAbstractAction.java (renamed from plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchAbstractAction.java)10
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchPopup.java119
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchPopupActions.java (renamed from plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopupActions.java)80
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchUtil.java77
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchesAction.java (renamed from plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchesAction.java)3
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgCommonBranchActions.java141
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgMultiRootBranchConfig.java50
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/command/HgCommitCommand.java24
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgCommandExecutor.java2
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/log/HgHistoryUtil.java6
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/log/HgLogProvider.java28
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgChangeProvider.java44
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgCurrentBinaryContentRevision.java18
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgCurrentContentRevision.java2
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/provider/commit/HgCheckinEnvironment.java114
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPushSupport.java44
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPushTargetPanel.java88
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/push/HgTarget.java1
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/push/PushTargetTextField.java63
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepoInfo.java16
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepository.java5
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java27
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryReader.java18
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/status/ui/HgStatusWidget.java2
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgConfigurationProjectPanel.form44
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgConfigurationProjectPanel.java11
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java22
31 files changed, 901 insertions, 435 deletions
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/HgProjectSettings.java b/plugins/hg4idea/src/org/zmlx/hg4idea/HgProjectSettings.java
index 936587d19755..8abac1bb0b1e 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/HgProjectSettings.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/HgProjectSettings.java
@@ -12,6 +12,8 @@
// limitations under the License.
package org.zmlx.hg4idea;
+import com.intellij.dvcs.branch.DvcsBranchSync;
+import com.intellij.dvcs.branch.DvcsSyncBranchSettings;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
@@ -24,7 +26,7 @@ import org.jetbrains.annotations.NotNull;
name = "hg4idea.settings",
storages = @Storage(file = StoragePathMacros.WORKSPACE_FILE)
)
-public class HgProjectSettings implements PersistentStateComponent<HgProjectSettings.State> {
+public class HgProjectSettings implements PersistentStateComponent<HgProjectSettings.State>, DvcsSyncBranchSettings {
@NotNull private final HgGlobalSettings myAppSettings;
@NotNull private final Project myProject;
@@ -37,10 +39,12 @@ public class HgProjectSettings implements PersistentStateComponent<HgProjectSett
}
public static class State {
+
public boolean myCheckIncoming = true;
public boolean myCheckOutgoing = true;
public Boolean CHECK_INCOMING_OUTGOING = null;
public boolean myIgnoreWhitespacesInAnnotations = true;
+ public DvcsBranchSync SYNC_SETTING = DvcsBranchSync.NOT_DECIDED;
}
public State getState() {
@@ -62,6 +66,15 @@ public class HgProjectSettings implements PersistentStateComponent<HgProjectSett
return myState.myIgnoreWhitespacesInAnnotations;
}
+ @NotNull
+ public DvcsBranchSync getSyncSetting() {
+ return myState.SYNC_SETTING;
+ }
+
+ public void setSyncSetting(@NotNull DvcsBranchSync syncSetting) {
+ myState.SYNC_SETTING = syncSetting;
+ }
+
public void setCheckIncomingOutgoing(boolean checkIncomingOutgoing) {
myState.CHECK_INCOMING_OUTGOING = checkIncomingOutgoing;
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalAction.java
index d6282ebe8786..8a521202aa3c 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalAction.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgAbstractGlobalAction.java
@@ -34,7 +34,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
-abstract class HgAbstractGlobalAction extends AnAction {
+public abstract class HgAbstractGlobalAction extends AnAction {
protected HgAbstractGlobalAction(Icon icon) {
super(icon);
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopup.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopup.java
deleted file mode 100644
index c31e14e348d8..000000000000
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopup.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright 2000-2013 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.dvcs.DvcsUtil;
-import com.intellij.dvcs.ui.BranchActionGroupPopup;
-import com.intellij.dvcs.ui.RootAction;
-import com.intellij.openapi.actionSystem.ActionGroup;
-import com.intellij.openapi.actionSystem.AnAction;
-import com.intellij.openapi.actionSystem.DefaultActionGroup;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.popup.ListPopup;
-import com.intellij.openapi.util.Condition;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.ui.popup.list.ListPopupImpl;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.zmlx.hg4idea.repo.HgRepository;
-import org.zmlx.hg4idea.util.HgUtil;
-
-import javax.swing.*;
-import java.util.List;
-
-/**
- * <p>
- * The popup which allows to quickly switch and control Hg branches.
- * </p>
- * <p>
- * Use {@link #asListPopup()} to achieve the {@link com.intellij.openapi.ui.popup.ListPopup} itself.
- * </p>
- *
- * @author NadyaZabrodina
- */
-public class HgBranchPopup {
-
- private final Project myProject;
-
- private final HgRepository myCurrentRepository;
- private final ListPopupImpl myPopup;
-
- public ListPopup asListPopup() {
- return myPopup;
- }
-
- /**
- * @param currentRepository Current repository, which means the repository of the currently open or selected file.
- */
- public static HgBranchPopup getInstance(@NotNull Project project, @NotNull HgRepository currentRepository) {
- return new HgBranchPopup(project, currentRepository);
- }
-
- private HgBranchPopup(@NotNull Project project, @NotNull HgRepository currentRepository) {
- myProject = project;
- myCurrentRepository = currentRepository;
- String title = createPopupTitle(currentRepository);
-
- Condition<AnAction> preselectActionCondition = new Condition<AnAction>() {
- @Override
- public boolean value(AnAction action) {
- return false;
- }
- };
- myPopup = new BranchActionGroupPopup(title, project, preselectActionCondition, createActions());
- setCurrentBranchInfo();
- }
-
-
- @NotNull
- private static String createPopupTitle(@NotNull HgRepository currentRepository) {
- String title = "Hg Branches";
- title += " in " + DvcsUtil.getShortRepositoryName(currentRepository);
- return title;
- }
-
- private void setCurrentBranchInfo() {
- String branchText = "Current branch : ";
- //always display heavy branch name for additional info //
- myPopup.setAdText(branchText + myCurrentRepository.getCurrentBranch(), SwingConstants.CENTER);
- }
-
-
- private ActionGroup createActions() {
- DefaultActionGroup popupGroup = new DefaultActionGroup(null, false);
- fillPopupWithCurrentRepositoryActions(popupGroup, createRepositoriesActions());
- popupGroup.addSeparator();
- return popupGroup;
- }
-
-
- @Nullable
- private DefaultActionGroup createRepositoriesActions() {
- List<VirtualFile> repositories = HgUtil.getHgRepositories(myProject);
- if (repositories.size() == 1) {
- return null; // if project has only one repository all branches, bookmarks and actions should be inline and no repository group needed
- }
- DefaultActionGroup popupGroup = new DefaultActionGroup(null, false);
- popupGroup.addSeparator("Repositories");
- boolean isMultiRepoConfig = repositories.size() > 1;
- for (VirtualFile repository : repositories) {
- HgRepository repo = HgUtil.getRepositoryManager(myProject).getRepositoryForRoot(repository);
- if (repo != null) {
- popupGroup.add(new RootAction<HgRepository>(repo, isMultiRepoConfig ? myCurrentRepository : null,
- new HgBranchPopupActions(repo.getProject(), repo).createActions(null),
- HgUtil.getDisplayableBranchOrBookmarkText(repo)));
- }
- }
- return popupGroup;
- }
-
- protected void fillPopupWithCurrentRepositoryActions(@NotNull DefaultActionGroup popupGroup, @Nullable DefaultActionGroup actions) {
- popupGroup.addAll(new HgBranchPopupActions(myProject, myCurrentRepository).createActions(actions));
- }
-}
-
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgCommonBranchActions.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgCommonBranchActions.java
deleted file mode 100644
index c79ae1ca0b7c..000000000000
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgCommonBranchActions.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * 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.ActionGroup;
-import com.intellij.openapi.actionSystem.AnAction;
-import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.fileEditor.FileDocumentManager;
-import com.intellij.openapi.progress.ProgressIndicator;
-import com.intellij.openapi.progress.Task;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vcs.VcsException;
-import com.intellij.openapi.vcs.VcsNotifier;
-import com.intellij.openapi.vcs.update.UpdatedFiles;
-import com.intellij.openapi.vfs.VirtualFile;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.zmlx.hg4idea.HgVcs;
-import org.zmlx.hg4idea.HgVcsMessages;
-import org.zmlx.hg4idea.command.HgMergeCommand;
-import org.zmlx.hg4idea.command.HgUpdateCommand;
-import org.zmlx.hg4idea.execution.HgCommandResult;
-import org.zmlx.hg4idea.provider.update.HgConflictResolver;
-import org.zmlx.hg4idea.provider.update.HgHeadMerger;
-import org.zmlx.hg4idea.repo.HgRepository;
-import org.zmlx.hg4idea.util.HgErrorUtil;
-
-public class HgCommonBranchActions extends ActionGroup {
-
- @NotNull protected final Project myProject;
- @NotNull protected String myBranchName;
- @NotNull protected final HgRepository mySelectedRepository;
-
- HgCommonBranchActions(@NotNull Project project, @NotNull HgRepository selectedRepository, @NotNull String branchName) {
- super("", true);
- myProject = project;
- myBranchName = branchName;
- mySelectedRepository = selectedRepository;
- getTemplatePresentation().setText(myBranchName, false); // no mnemonics
- }
-
- @NotNull
- @Override
- public AnAction[] getChildren(@Nullable AnActionEvent e) {
- return new AnAction[]{
- new UpdateAction(myProject, mySelectedRepository, myBranchName),
- new MergeAction(myProject, mySelectedRepository, myBranchName)
- };
- }
-
- private static class MergeAction extends HgBranchAbstractAction {
-
- public MergeAction(@NotNull Project project,
- @NotNull HgRepository selectedRepository,
- @NotNull String branchName) {
- super(project, "Merge", selectedRepository, branchName);
- }
-
- @Override
- public void actionPerformed(AnActionEvent e) {
- FileDocumentManager.getInstance().saveAllDocuments();
- final UpdatedFiles updatedFiles = UpdatedFiles.create();
- final HgMergeCommand hgMergeCommand = new HgMergeCommand(myProject, mySelectedRepository.getRoot());
- hgMergeCommand.setRevision(myBranchName);//there is no difference between branch or revision or bookmark as parameter to merge,
- // we need just a string
- new Task.Backgroundable(myProject, "Merging changes...") {
- @Override
- public void run(@NotNull ProgressIndicator indicator) {
- try {
- new HgHeadMerger(myProject, hgMergeCommand)
- .merge(mySelectedRepository.getRoot());
- new HgConflictResolver(myProject, updatedFiles).resolve(mySelectedRepository.getRoot());
- }
-
- catch (VcsException exception) {
- assert myProject != null; // myProject couldn't be null, see annotation for Merge action
- if (exception.isWarning()) {
- VcsNotifier.getInstance(myProject).notifyWarning("Warning during merge", exception.getMessage());
- }
- else {
- VcsNotifier.getInstance(myProject).notifyError("Exception during merge", exception.getMessage());
- }
- }
- catch (Exception e1) {
- HgAbstractGlobalAction.handleException(myProject, e1);
- }
- }
- }.queue();
- }
- }
-
- private static class UpdateAction extends HgBranchAbstractAction {
-
- public UpdateAction(@NotNull Project project,
- @NotNull HgRepository selectedRepository,
- @NotNull String branchName) {
- super(project, "Update", selectedRepository, branchName);
- }
-
- @Override
- public void actionPerformed(AnActionEvent e) {
- final VirtualFile repository = mySelectedRepository.getRoot();
- FileDocumentManager.getInstance().saveAllDocuments();
- final HgUpdateCommand hgUpdateCommand = new HgUpdateCommand(myProject, repository);
- hgUpdateCommand.setBranch(myBranchName);
- new Task.Backgroundable(myProject, HgVcsMessages.message("action.hg4idea.updateTo.description", myBranchName)) {
- @Override
- public void run(@NotNull ProgressIndicator indicator) {
- HgCommandResult result = hgUpdateCommand.execute();
- assert myProject != null; // myProject couldn't be null, see annotation for updateTo action
- if (HgErrorUtil.hasErrorsInCommandExecution(result)) {
- new HgCommandResultNotifier(myProject).notifyError(result, "", "Update failed");
- new HgConflictResolver(myProject).resolve(repository);
- }
- myProject.getMessageBus().syncPublisher(HgVcs.BRANCH_TOPIC).update(myProject, null);
- }
- }.queue();
- }
- }
-} \ No newline at end of file
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchAbstractAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchAbstractAction.java
index 78b67013ed54..3998dedd0cc5 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchAbstractAction.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchAbstractAction.java
@@ -13,24 +13,26 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.zmlx.hg4idea.action;
+package org.zmlx.hg4idea.branch;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.zmlx.hg4idea.repo.HgRepository;
+import java.util.List;
+
public abstract class HgBranchAbstractAction extends DumbAwareAction {
@NotNull protected final Project myProject;
- @NotNull protected final HgRepository mySelectedRepository;
+ @NotNull protected final List<HgRepository> myRepositories;
@NotNull protected final String myBranchName;
public HgBranchAbstractAction(@NotNull Project project, @NotNull String title,
- @NotNull HgRepository selectedRepository,
+ @NotNull List<HgRepository> repositories,
@NotNull String branchName) {
super(title);
myProject = project;
- mySelectedRepository = selectedRepository;
+ myRepositories = repositories;
myBranchName = branchName;
}
} \ No newline at end of file
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchPopup.java b/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchPopup.java
new file mode 100644
index 000000000000..c0d6f58d5e0e
--- /dev/null
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchPopup.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2000-2013 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.branch;
+
+import com.intellij.dvcs.branch.DvcsBranchPopup;
+import com.intellij.dvcs.repo.AbstractRepositoryManager;
+import com.intellij.dvcs.ui.RootAction;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.DefaultActionGroup;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Condition;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.zmlx.hg4idea.HgProjectSettings;
+import org.zmlx.hg4idea.repo.HgRepository;
+import org.zmlx.hg4idea.repo.HgRepositoryManager;
+import org.zmlx.hg4idea.util.HgUtil;
+
+import javax.swing.*;
+import java.util.List;
+
+/**
+ * <p>
+ * The popup which allows to quickly switch and control Hg branches.
+ * </p>
+ * <p>
+ * Use {@link #asListPopup()} to achieve the {@link com.intellij.openapi.ui.popup.ListPopup} itself.
+ * </p>
+ */
+public class HgBranchPopup extends DvcsBranchPopup<HgRepository> {
+
+ /**
+ * @param currentRepository Current repository, which means the repository of the currently open or selected file.
+ */
+ public static HgBranchPopup getInstance(@NotNull Project project, @NotNull HgRepository currentRepository) {
+
+ HgRepositoryManager manager = HgUtil.getRepositoryManager(project);
+ HgProjectSettings hgProjectSettings = ServiceManager.getService(project, HgProjectSettings.class);
+ HgMultiRootBranchConfig hgMultiRootBranchConfig = new HgMultiRootBranchConfig(manager.getRepositories());
+
+ Condition<AnAction> preselectActionCondition = new Condition<AnAction>() {
+ @Override
+ public boolean value(AnAction action) {
+ return false;
+ }
+ };
+ return new HgBranchPopup(currentRepository, manager, hgMultiRootBranchConfig, hgProjectSettings,
+ preselectActionCondition);
+ }
+
+ private HgBranchPopup(@NotNull HgRepository currentRepository,
+ @NotNull HgRepositoryManager repositoryManager,
+ @NotNull HgMultiRootBranchConfig hgMultiRootBranchConfig, @NotNull HgProjectSettings vcsSettings,
+ @NotNull Condition<AnAction> preselectActionCondition) {
+ super(currentRepository, repositoryManager, hgMultiRootBranchConfig, vcsSettings, preselectActionCondition);
+ }
+
+ protected void setCurrentBranchInfo() {
+ String branchText = "Current branch : ";
+ //always display heavy branch name for additional info //
+ myPopup.setAdText(branchText + myCurrentRepository.getCurrentBranch(), SwingConstants.CENTER);
+ }
+
+ @Override
+ protected void fillWithCommonRepositoryActions(@NotNull DefaultActionGroup popupGroup,
+ @NotNull AbstractRepositoryManager<HgRepository> repositoryManager) {
+ List<HgRepository> allRepositories = repositoryManager.getRepositories();
+ popupGroup.add(new HgBranchPopupActions.HgNewBranchAction(myProject, allRepositories, myCurrentRepository));
+ popupGroup.addAction(new HgBranchPopupActions.HgNewBookmarkAction(myProject, allRepositories, myCurrentRepository));
+ popupGroup.addAction(new HgBranchPopupActions.HgShowUnnamedHeadsForCurrentBranchAction(myProject, myCurrentRepository));
+ popupGroup.addAll(createRepositoriesActions());
+
+ popupGroup.addSeparator("Common Branches");
+ for (String branch : myMultiRootBranchConfig.getLocalBranchNames()) {
+ List<HgRepository> repositories = filterRepositoriesNotOnThisBranch(branch, allRepositories);
+ if (!repositories.isEmpty()) {
+ popupGroup.add(new HgCommonBranchActions(myProject, repositories, branch));
+ }
+ }
+ popupGroup.addSeparator("Common Bookmarks");
+ for (String branch : ((HgMultiRootBranchConfig)myMultiRootBranchConfig).getBookmarkNames()) {
+ List<HgRepository> repositories = filterRepositoriesNotOnThisBranch(branch, allRepositories);
+ if (!repositories.isEmpty()) {
+ popupGroup.add(new HgBranchPopupActions.BookmarkActions(myProject, repositories, branch));
+ }
+ }
+ }
+
+ @NotNull
+ protected DefaultActionGroup createRepositoriesActions() {
+ DefaultActionGroup popupGroup = new DefaultActionGroup(null, false);
+ popupGroup.addSeparator("Repositories");
+ for (HgRepository repository : myRepositoryManager.getRepositories()) {
+ popupGroup.add(new RootAction<HgRepository>(repository, highlightCurrentRepo() ? myCurrentRepository : null,
+ new HgBranchPopupActions(repository.getProject(), repository).createActions(null),
+ HgUtil.getDisplayableBranchOrBookmarkText(repository)));
+ }
+ return popupGroup;
+ }
+
+ protected void fillPopupWithCurrentRepositoryActions(@NotNull DefaultActionGroup popupGroup, @Nullable DefaultActionGroup actions) {
+ popupGroup.addAll(new HgBranchPopupActions(myProject, myCurrentRepository).createActions(actions));
+ }
+}
+
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopupActions.java b/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchPopupActions.java
index 45dd12bd9c81..10b97235f559 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopupActions.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchPopupActions.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.zmlx.hg4idea.action;
+package org.zmlx.hg4idea.branch;
import com.intellij.dvcs.DvcsUtil;
import com.intellij.dvcs.repo.Repository;
@@ -35,6 +35,8 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.HgNameWithHashInfo;
import org.zmlx.hg4idea.HgRevisionNumber;
+import org.zmlx.hg4idea.action.HgAbstractGlobalAction;
+import org.zmlx.hg4idea.action.HgCommandResultNotifier;
import org.zmlx.hg4idea.command.HgBookmarkCommand;
import org.zmlx.hg4idea.command.HgBranchCreateCommand;
import org.zmlx.hg4idea.command.HgWorkingCopyRevisionsCommand;
@@ -73,7 +75,7 @@ public class HgBranchPopupActions {
List<String> bookmarkNames = getNamesWithoutHashes(myRepository.getBookmarks());
String currentBookmark = myRepository.getCurrentBookmark();
for (String bookmark : bookmarkNames) {
- AnAction bookmarkAction = new BookmarkActions(myProject, myRepository, bookmark);
+ AnAction bookmarkAction = new BookmarkActions(myProject, Collections.singletonList(myRepository), bookmark);
if (bookmark.equals(currentBookmark)) {
bookmarkAction.getTemplatePresentation().setIcon(PlatformIcons.CHECK_ICON);
}
@@ -85,13 +87,13 @@ public class HgBranchPopupActions {
Collections.sort(branchNamesList);
for (String branch : branchNamesList) {
if (!branch.equals(myRepository.getCurrentBranch())) { // don't show current branch in the list
- popupGroup.add(new HgCommonBranchActions(myProject, myRepository, branch));
+ popupGroup.add(new HgCommonBranchActions(myProject, Collections.singletonList(myRepository), branch));
}
}
return popupGroup;
}
- private static class HgNewBranchAction extends NewBranchAction<HgRepository> {
+ public static class HgNewBranchAction extends NewBranchAction<HgRepository> {
@NotNull final HgRepository myPreselectedRepo;
HgNewBranchAction(@NotNull Project project, @NotNull List<HgRepository> repositories, @NotNull HgRepository preselectedRepo) {
@@ -105,25 +107,27 @@ public class HgBranchPopupActions {
if (name == null) {
return;
}
- try {
- new HgBranchCreateCommand(myProject, myPreselectedRepo.getRoot(), name).execute(new HgCommandResultHandler() {
- @Override
- public void process(@Nullable HgCommandResult result) {
- myPreselectedRepo.update();
- if (HgErrorUtil.hasErrorsInCommandExecution(result)) {
- new HgCommandResultNotifier(myProject)
- .notifyError(result, "Creation failed", "Branch creation [" + name + "] failed");
+ for (final HgRepository repository : myRepositories) {
+ try {
+ new HgBranchCreateCommand(myProject, repository.getRoot(), name).execute(new HgCommandResultHandler() {
+ @Override
+ public void process(@Nullable HgCommandResult result) {
+ repository.update();
+ if (HgErrorUtil.hasErrorsInCommandExecution(result)) {
+ new HgCommandResultNotifier(myProject)
+ .notifyError(result, "Creation failed", "Branch creation [" + name + "] failed");
+ }
}
- }
- });
- }
- catch (HgCommandException exception) {
- HgAbstractGlobalAction.handleException(myProject, "Can't create new branch: ", exception);
+ });
+ }
+ catch (HgCommandException exception) {
+ HgAbstractGlobalAction.handleException(myProject, "Can't create new branch: ", exception);
+ }
}
}
}
- private static class HgNewBookmarkAction extends DumbAwareAction {
+ public static class HgNewBookmarkAction extends DumbAwareAction {
@NotNull protected final List<HgRepository> myRepositories;
@NotNull protected Project myProject;
@NotNull final HgRepository myPreselectedRepo;
@@ -149,18 +153,20 @@ public class HgBranchPopupActions {
final HgBookmarkDialog bookmarkDialog = new HgBookmarkDialog(myPreselectedRepo);
bookmarkDialog.show();
if (bookmarkDialog.isOK()) {
- try {
- final String name = bookmarkDialog.getName();
- new HgBookmarkCommand(myProject, myPreselectedRepo.getRoot(), name).createBookmark(bookmarkDialog.isActive());
- }
- catch (HgCommandException exception) {
- HgAbstractGlobalAction.handleException(myProject, exception);
+ final String name = bookmarkDialog.getName();
+ for (HgRepository repository : myRepositories) {
+ try {
+ new HgBookmarkCommand(myProject, repository.getRoot(), name).createBookmark(bookmarkDialog.isActive());
+ }
+ catch (HgCommandException exception) {
+ HgAbstractGlobalAction.handleException(myProject, exception);
+ }
}
}
}
}
- static private class HgShowUnnamedHeadsForCurrentBranchAction extends ActionGroup {
+ public static class HgShowUnnamedHeadsForCurrentBranchAction extends ActionGroup {
@NotNull final Project myProject;
@NotNull final HgRepository myRepository;
@NotNull final String myCurrentBranchName;
@@ -210,7 +216,7 @@ public class HgBranchPopupActions {
public AnAction[] getChildren(@Nullable AnActionEvent e) {
List<AnAction> branchHeadActions = new ArrayList<AnAction>();
for (Hash hash : myHeads) {
- branchHeadActions.add(new HgCommonBranchActions(myProject, myRepository, hash.toShortString()));
+ branchHeadActions.add(new HgCommonBranchActions(myProject, Collections.singletonList(myRepository), hash.toShortString()));
}
return ContainerUtil.toArray(branchHeadActions, new AnAction[branchHeadActions.size()]);
}
@@ -232,29 +238,31 @@ public class HgBranchPopupActions {
*/
static class BookmarkActions extends HgCommonBranchActions {
- BookmarkActions(@NotNull Project project, @NotNull HgRepository selectedRepository, @NotNull String branchName) {
- super(project, selectedRepository, branchName);
+ BookmarkActions(@NotNull Project project, @NotNull List<HgRepository> repositories, @NotNull String branchName) {
+ super(project, repositories, branchName);
}
@NotNull
@Override
public AnAction[] getChildren(@Nullable AnActionEvent e) {
- return ArrayUtil.append(super.getChildren(e), new DeleteBookmarkAction(myProject, mySelectedRepository, myBranchName));
+ return ArrayUtil.append(super.getChildren(e), new DeleteBookmarkAction(myProject, myRepositories, myBranchName));
}
private static class DeleteBookmarkAction extends HgBranchAbstractAction {
- DeleteBookmarkAction(@NotNull Project project, @NotNull HgRepository selectedRepository, @NotNull String branchName) {
- super(project, "Delete", selectedRepository, branchName);
+ DeleteBookmarkAction(@NotNull Project project, @NotNull List<HgRepository> repositories, @NotNull String branchName) {
+ super(project, "Delete", repositories, branchName);
}
@Override
public void actionPerformed(AnActionEvent e) {
- try {
- new HgBookmarkCommand(myProject, mySelectedRepository.getRoot(), myBranchName).deleteBookmark();
- }
- catch (HgCommandException exception) {
- HgAbstractGlobalAction.handleException(myProject, exception);
+ for (HgRepository repository : myRepositories) {
+ try {
+ new HgBookmarkCommand(myProject, repository.getRoot(), myBranchName).deleteBookmark();
+ }
+ catch (HgCommandException exception) {
+ HgAbstractGlobalAction.handleException(myProject, exception);
+ }
}
}
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchUtil.java b/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchUtil.java
new file mode 100644
index 000000000000..9dbdd3ea7f65
--- /dev/null
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchUtil.java
@@ -0,0 +1,77 @@
+/*
+ * 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.branch;
+
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.vcs.log.Hash;
+import org.jetbrains.annotations.NotNull;
+import org.zmlx.hg4idea.HgNameWithHashInfo;
+import org.zmlx.hg4idea.repo.HgRepository;
+import org.zmlx.hg4idea.util.HgUtil;
+
+import java.util.*;
+
+public class HgBranchUtil {
+
+ /**
+ * Only common hg heavy branches
+ */
+ @NotNull
+ public static Collection<String> getCommonBranches(@NotNull Collection<HgRepository> repositories) {
+ Collection<String> commonBranches = null;
+ for (HgRepository repository : repositories) {
+ Map<String, Set<Hash>> branchesWithHashes = repository.getBranches();
+ Collection<String> names = branchesWithHashes.keySet();
+ if (commonBranches == null) {
+ commonBranches = names;
+ }
+ else {
+ commonBranches = ContainerUtil.intersection(commonBranches, names);
+ }
+ }
+ if (commonBranches != null) {
+ ArrayList<String> common = new ArrayList<String>(commonBranches);
+ Collections.sort(common);
+ return common;
+ }
+ else {
+ return Collections.emptyList();
+ }
+ }
+
+ @NotNull
+ public static Collection<String> getCommonBookmarks(@NotNull Collection<HgRepository> repositories) {
+ Collection<String> commonBookmarkNames = null;
+ for (HgRepository repository : repositories) {
+ Collection<HgNameWithHashInfo> bookmarksInfo = repository.getBookmarks();
+ Collection<String> names = HgUtil.getNamesWithoutHashes(bookmarksInfo);
+ if (commonBookmarkNames == null) {
+ commonBookmarkNames = names;
+ }
+ else {
+ commonBookmarkNames = ContainerUtil.intersection(commonBookmarkNames, names);
+ }
+ }
+ if (commonBookmarkNames != null) {
+ ArrayList<String> common = new ArrayList<String>(commonBookmarkNames);
+ Collections.sort(common);
+ return common;
+ }
+ else {
+ return Collections.emptyList();
+ }
+ }
+}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchesAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchesAction.java
index d799cde1705c..b078da12548f 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchesAction.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgBranchesAction.java
@@ -13,11 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.zmlx.hg4idea.action;
+package org.zmlx.hg4idea.branch;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.zmlx.hg4idea.action.HgAbstractGlobalSingleRepoAction;
import org.zmlx.hg4idea.repo.HgRepository;
import java.util.Collection;
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgCommonBranchActions.java b/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgCommonBranchActions.java
new file mode 100644
index 000000000000..ecba99f7b532
--- /dev/null
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgCommonBranchActions.java
@@ -0,0 +1,141 @@
+/*
+ * 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.branch;
+
+import com.intellij.openapi.actionSystem.ActionGroup;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.Task;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vcs.VcsException;
+import com.intellij.openapi.vcs.VcsNotifier;
+import com.intellij.openapi.vcs.update.UpdatedFiles;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.zmlx.hg4idea.HgVcs;
+import org.zmlx.hg4idea.HgVcsMessages;
+import org.zmlx.hg4idea.action.HgAbstractGlobalAction;
+import org.zmlx.hg4idea.action.HgCommandResultNotifier;
+import org.zmlx.hg4idea.command.HgMergeCommand;
+import org.zmlx.hg4idea.command.HgUpdateCommand;
+import org.zmlx.hg4idea.execution.HgCommandResult;
+import org.zmlx.hg4idea.provider.update.HgConflictResolver;
+import org.zmlx.hg4idea.provider.update.HgHeadMerger;
+import org.zmlx.hg4idea.repo.HgRepository;
+import org.zmlx.hg4idea.util.HgErrorUtil;
+
+import java.util.List;
+
+public class HgCommonBranchActions extends ActionGroup {
+
+ @NotNull protected final Project myProject;
+ @NotNull protected String myBranchName;
+ @NotNull List<HgRepository> myRepositories;
+
+ HgCommonBranchActions(@NotNull Project project, @NotNull List<HgRepository> repositories, @NotNull String branchName) {
+ super("", true);
+ myProject = project;
+ myBranchName = branchName;
+ myRepositories = repositories;
+ getTemplatePresentation().setText(myBranchName, false); // no mnemonics
+ }
+
+ @NotNull
+ @Override
+ public AnAction[] getChildren(@Nullable AnActionEvent e) {
+ return new AnAction[]{
+ new UpdateAction(myProject, myRepositories, myBranchName),
+ new MergeAction(myProject, myRepositories, myBranchName)
+ };
+ }
+
+ private static class MergeAction extends HgBranchAbstractAction {
+
+ public MergeAction(@NotNull Project project,
+ @NotNull List<HgRepository> repositories,
+ @NotNull String branchName) {
+ super(project, "Merge", repositories, branchName);
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ FileDocumentManager.getInstance().saveAllDocuments();
+ final UpdatedFiles updatedFiles = UpdatedFiles.create();
+ for (final HgRepository repository : myRepositories) {
+ final HgMergeCommand hgMergeCommand = new HgMergeCommand(myProject, repository.getRoot());
+ hgMergeCommand.setRevision(myBranchName);//there is no difference between branch or revision or bookmark as parameter to merge,
+ // we need just a string
+ new Task.Backgroundable(myProject, "Merging changes...") {
+ @Override
+ public void run(@NotNull ProgressIndicator indicator) {
+ try {
+ new HgHeadMerger(myProject, hgMergeCommand)
+ .merge(repository.getRoot());
+ new HgConflictResolver(myProject, updatedFiles).resolve(repository.getRoot());
+ }
+
+ catch (VcsException exception) {
+ assert myProject != null; // myProject couldn't be null, see annotation for Merge action
+ if (exception.isWarning()) {
+ VcsNotifier.getInstance(myProject).notifyWarning("Warning during merge", exception.getMessage());
+ }
+ else {
+ VcsNotifier.getInstance(myProject).notifyError("Exception during merge", exception.getMessage());
+ }
+ }
+ catch (Exception e1) {
+ HgAbstractGlobalAction.handleException(myProject, e1);
+ }
+ }
+ }.queue();
+ }
+ }
+ }
+
+ private static class UpdateAction extends HgBranchAbstractAction {
+
+ public UpdateAction(@NotNull Project project,
+ @NotNull List<HgRepository> repositories,
+ @NotNull String branchName) {
+ super(project, "Update", repositories, branchName);
+ }
+
+ @Override
+ public void actionPerformed(AnActionEvent e) {
+ FileDocumentManager.getInstance().saveAllDocuments();
+ for (HgRepository repo : myRepositories) {
+ final VirtualFile repository = repo.getRoot();
+ final HgUpdateCommand hgUpdateCommand = new HgUpdateCommand(myProject, repository);
+ hgUpdateCommand.setBranch(myBranchName);
+ new Task.Backgroundable(myProject, HgVcsMessages.message("action.hg4idea.updateTo.description", myBranchName)) {
+ @Override
+ public void run(@NotNull ProgressIndicator indicator) {
+ HgCommandResult result = hgUpdateCommand.execute();
+ assert myProject != null; // myProject couldn't be null, see annotation for updateTo action
+ if (HgErrorUtil.hasErrorsInCommandExecution(result)) {
+ new HgCommandResultNotifier(myProject).notifyError(result, "", "Update failed");
+ new HgConflictResolver(myProject).resolve(repository);
+ }
+ myProject.getMessageBus().syncPublisher(HgVcs.BRANCH_TOPIC).update(myProject, repository);
+ }
+ }.queue();
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgMultiRootBranchConfig.java b/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgMultiRootBranchConfig.java
new file mode 100644
index 000000000000..e762fb8992ab
--- /dev/null
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/branch/HgMultiRootBranchConfig.java
@@ -0,0 +1,50 @@
+/*
+ * 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.branch;
+
+import com.intellij.dvcs.branch.DvcsMultiRootBranchConfig;
+import org.jetbrains.annotations.NotNull;
+import org.zmlx.hg4idea.repo.HgRepository;
+
+import java.util.Collection;
+
+public class HgMultiRootBranchConfig extends DvcsMultiRootBranchConfig<HgRepository> {
+
+ public HgMultiRootBranchConfig(@NotNull Collection<HgRepository> repositories) {
+ super(repositories);
+ }
+
+ @NotNull
+ @Override
+ public Collection<String> getLocalBranchNames() {
+ return HgBranchUtil.getCommonBranches(myRepositories);
+ }
+
+ @NotNull
+ Collection<String> getBookmarkNames() {
+ return HgBranchUtil.getCommonBookmarks(myRepositories);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ for (HgRepository repository : myRepositories) {
+ sb.append(repository.getPresentableUrl()).append(":").append(repository.getCurrentBranchName()).append(":")
+ .append(repository.getState());
+ }
+ return sb.toString();
+ }
+}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgCommitCommand.java b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgCommitCommand.java
index 5aa632e0a4ea..794c7096d207 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgCommitCommand.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/command/HgCommitCommand.java
@@ -53,6 +53,7 @@ public class HgCommitCommand {
private final boolean myAmend;
private Set<HgFile> myFiles = Collections.emptySet();
+ @NotNull private List<String> mySubrepos = Collections.emptyList();
public HgCommitCommand(Project project, @NotNull VirtualFile root, String message, boolean amend) {
myProject = project;
@@ -70,6 +71,10 @@ public class HgCommitCommand {
myFiles = files;
}
+ public void setSubrepos(@NotNull List<String> subrepos) {
+ mySubrepos = subrepos;
+ }
+
public void execute() throws HgCommandException, VcsException {
if (StringUtil.isEmptyOrSpaces(myMessage)) {
throw new HgCommandException(HgVcsMessages.message("hg4idea.commit.error.messageEmpty"));
@@ -88,7 +93,8 @@ public class HgCommitCommand {
});
List<List<String>> chunkedCommits = VcsFileUtil.chunkRelativePaths(relativePaths);
int size = chunkedCommits.size();
- commitChunkFiles(chunkedCommits.get(0), myAmend);
+ // commit with subrepo should be first, because it's not possible to amend with --subrepos argument;
+ commitChunkFiles(chunkedCommits.get(0), myAmend, !mySubrepos.isEmpty());
HgVcs vcs = HgVcs.getInstance(myProject);
boolean amendCommit = vcs != null && vcs.getVersion().isAmendSupported();
for (int i = 1; i < size; i++) {
@@ -105,14 +111,23 @@ public class HgCommitCommand {
messageBus.syncPublisher(HgVcs.BRANCH_TOPIC).update(myProject, null);
}
- private void commitChunkFiles(List<String> chunk, boolean amendCommit) throws VcsException {
+ private void commitChunkFiles(@NotNull List<String> chunk, boolean amendCommit) throws VcsException {
+ commitChunkFiles(chunk, amendCommit, false);
+ }
+
+ private void commitChunkFiles(@NotNull List<String> chunk, boolean amendCommit, boolean withSubrepos) throws VcsException {
List<String> parameters = new LinkedList<String>();
parameters.add("--logfile");
parameters.add(saveCommitMessage().getAbsolutePath());
- parameters.addAll(chunk);
- if (amendCommit) {
+ // note: for now mercurial could not perform amend commit with -S option
+ if (withSubrepos) {
+ parameters.add("-S");
+ parameters.addAll(mySubrepos);
+ }
+ else if (amendCommit) {
parameters.add("--amend");
}
+ parameters.addAll(chunk);
HgCommandExecutor executor = new HgCommandExecutor(myProject);
executor.setCharset(myCharset);
ensureSuccess(executor.executeInCurrentThread(myRoot, "commit", parameters));
@@ -129,5 +144,4 @@ public class HgCommitCommand {
}
return tempFile;
}
-
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgCommandExecutor.java b/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgCommandExecutor.java
index 7cf8f65559ea..f27d6a0d6550 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgCommandExecutor.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/execution/HgCommandExecutor.java
@@ -49,7 +49,7 @@ import java.util.List;
*/
public class HgCommandExecutor {
- protected static final Logger LOG = Logger.getInstance(HgRemoteCommandExecutor.class.getName());
+ protected static final Logger LOG = Logger.getInstance(HgCommandExecutor.class.getName());
private static final List<String> DEFAULT_OPTIONS = Arrays.asList("--config", "ui.merge=internal:merge");
protected final Project myProject;
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgHistoryUtil.java b/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgHistoryUtil.java
index de565484e2d5..2d3a7bce191b 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgHistoryUtil.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgHistoryUtil.java
@@ -54,9 +54,9 @@ public class HgHistoryUtil {
}
@NotNull
- public static List<? extends VcsCommitMetadata> loadMetadata(@NotNull final Project project,
- @NotNull final VirtualFile root, int limit,
- @NotNull List<String> parameters) throws VcsException {
+ public static List<VcsCommitMetadata> loadMetadata(@NotNull final Project project,
+ @NotNull final VirtualFile root, int limit,
+ @NotNull List<String> parameters) throws VcsException {
final VcsLogObjectsFactory factory = getObjectsFactoryWithDisposeCheck(project);
if (factory == null) {
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgLogProvider.java b/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgLogProvider.java
index 3b989e448b61..109e83899e5b 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgLogProvider.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgLogProvider.java
@@ -22,9 +22,11 @@ import com.intellij.openapi.util.Couple;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.VcsKey;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.CollectConsumer;
import com.intellij.util.Consumer;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.vcs.log.*;
+import com.intellij.vcs.log.impl.LogDataImpl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.HgNameWithHashInfo;
@@ -59,18 +61,23 @@ public class HgLogProvider implements VcsLogProvider {
@NotNull
@Override
- public List<? extends VcsCommitMetadata> readFirstBlock(@NotNull VirtualFile root,
- @NotNull Requirements requirements) throws VcsException {
- return HgHistoryUtil.loadMetadata(myProject, root, requirements.getCommitCount(), Collections.<String>emptyList());
+ public DetailedLogData readFirstBlock(@NotNull VirtualFile root,
+ @NotNull Requirements requirements) throws VcsException {
+ List<VcsCommitMetadata> commits = HgHistoryUtil.loadMetadata(myProject, root, requirements.getCommitCount(),
+ Collections.<String>emptyList());
+ return new LogDataImpl(readAllRefs(root), commits);
}
@Override
- public void readAllHashes(@NotNull VirtualFile root, @NotNull Consumer<VcsUser> userRegistry,
- @NotNull Consumer<TimedVcsCommit> commitConsumer) throws VcsException {
- List<TimedVcsCommit> commits = HgHistoryUtil.readAllHashes(myProject, root, userRegistry, Collections.<String>emptyList());
+ @NotNull
+ public LogData readAllHashes(@NotNull VirtualFile root, @NotNull final Consumer<TimedVcsCommit> commitConsumer) throws VcsException {
+ Set<VcsUser> userRegistry = ContainerUtil.newHashSet();
+ List<TimedVcsCommit> commits = HgHistoryUtil.readAllHashes(myProject, root, new CollectConsumer<VcsUser>(userRegistry),
+ Collections.<String>emptyList());
for (TimedVcsCommit commit : commits) {
commitConsumer.consume(commit);
}
+ return new LogDataImpl(readAllRefs(root), userRegistry);
}
@NotNull
@@ -87,16 +94,15 @@ public class HgLogProvider implements VcsLogProvider {
}
@NotNull
- @Override
- public Collection<VcsRef> readAllRefs(@NotNull VirtualFile root) throws VcsException {
+ private Set<VcsRef> readAllRefs(@NotNull VirtualFile root) throws VcsException {
myRepositoryManager.waitUntilInitialized();
if (myProject.isDisposed()) {
- return Collections.emptyList();
+ return Collections.emptySet();
}
HgRepository repository = myRepositoryManager.getRepositoryForRoot(root);
if (repository == null) {
LOG.error("Repository not found for root " + root);
- return Collections.emptyList();
+ return Collections.emptySet();
}
repository.update();
@@ -106,7 +112,7 @@ public class HgLogProvider implements VcsLogProvider {
Collection<HgNameWithHashInfo> tags = repository.getTags();
Collection<HgNameWithHashInfo> localTags = repository.getLocalTags();
- Collection<VcsRef> refs = new ArrayList<VcsRef>(branches.size() + bookmarks.size());
+ Set<VcsRef> refs = new HashSet<VcsRef>(branches.size() + bookmarks.size());
for (Map.Entry<String, Set<Hash>> entry : branches.entrySet()) {
String branchName = entry.getKey();
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgChangeProvider.java b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgChangeProvider.java
index 02e49354f3ab..14a288171504 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgChangeProvider.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgChangeProvider.java
@@ -17,19 +17,24 @@ import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.*;
import com.intellij.openapi.vcs.changes.*;
+import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.ui.JBColor;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.vcsUtil.VcsUtil;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.*;
import org.zmlx.hg4idea.command.HgResolveCommand;
import org.zmlx.hg4idea.command.HgResolveStatusEnum;
import org.zmlx.hg4idea.command.HgStatusCommand;
import org.zmlx.hg4idea.command.HgWorkingCopyRevisionsCommand;
+import org.zmlx.hg4idea.repo.HgRepository;
import org.zmlx.hg4idea.util.HgUtil;
-import java.awt.*;
+import java.io.File;
import java.util.*;
-import java.util.List;
public class HgChangeProvider implements ChangeProvider {
@@ -38,7 +43,7 @@ public class HgChangeProvider implements ChangeProvider {
public static final FileStatus COPIED = FileStatusFactory.getInstance().createFileStatus("COPIED", "Copied", FileStatus.COLOR_ADDED);
public static final FileStatus RENAMED = FileStatusFactory.getInstance().createFileStatus("RENAMED", "Renamed",
- Color.cyan.darker().darker());
+ JBColor.CYAN.darker().darker());
private static final EnumMap<HgFileStatusEnum, HgChangeProcessor> PROCESSORS =
new EnumMap<HgFileStatusEnum, HgChangeProcessor>(HgFileStatusEnum.class);
@@ -85,21 +90,42 @@ public class HgChangeProvider implements ChangeProvider {
final Map<HgFile, HgResolveStatusEnum> list = new HgResolveCommand(myProject).getListSynchronously(repo);
hgChanges.addAll(new HgStatusCommand.Builder(true).build(myProject).execute(repo, entry.getValue()));
+ final HgRepository hgRepo = HgUtil.getRepositoryForFile(myProject, repo);
+ if (hgRepo != null && hgRepo.hasSubrepos()) {
+ hgChanges.addAll(ContainerUtil.mapNotNull(hgRepo.getSubrepos(), new Function<HgNameWithHashInfo, HgChange>() {
+ @Override
+ public HgChange fun(HgNameWithHashInfo info) {
+ return findChange(hgRepo, info);
+ }
+ }));
+ }
+
sendChanges(builder, hgChanges, list, workingRevision, parentRevision);
}
return hgChanges;
}
+ @Nullable
+ private HgChange findChange(@NotNull HgRepository hgRepo, @NotNull HgNameWithHashInfo info) {
+ File file = new File(hgRepo.getRoot().getPath(), info.getName());
+ VirtualFile virtualSubrepoFile = VfsUtil.findFileByIoFile(file, false);
+ HgRepository subrepo = HgUtil.getRepositoryForFile(myProject, virtualSubrepoFile);
+ if (subrepo != null && !info.getHash().asString().equals(subrepo.getCurrentRevision())) {
+ return new HgChange(new HgFile(hgRepo.getRoot(), new FilePathImpl(virtualSubrepoFile)), HgFileStatusEnum.MODIFIED);
+ }
+ return null;
+ }
+
private void sendChanges(ChangelistBuilder builder, Set<HgChange> changes,
- Map<HgFile, HgResolveStatusEnum> resolveStatus, HgRevisionNumber workingRevision,
- HgRevisionNumber parentRevision) {
+ Map<HgFile, HgResolveStatusEnum> resolveStatus, HgRevisionNumber workingRevision,
+ HgRevisionNumber parentRevision) {
for (HgChange change : changes) {
HgFile afterFile = change.afterFile();
HgFile beforeFile = change.beforeFile();
HgFileStatusEnum status = change.getStatus();
if (resolveStatus.containsKey(afterFile)
- && resolveStatus.get(afterFile) == HgResolveStatusEnum.UNRESOLVED) {
+ && resolveStatus.get(afterFile) == HgResolveStatusEnum.UNRESOLVED) {
builder.processChange(
new Change(
new HgContentRevision(myProject, beforeFile, parentRevision),
@@ -286,9 +312,9 @@ public class HgChangeProvider implements ChangeProvider {
HgFile afterFile
);
- final void processChange(ContentRevision contentRevisionBefore,
- ContentRevision contentRevisionAfter, FileStatus fileStatus,
- ChangelistBuilder builder, VcsKey vcsKey) {
+ static void processChange(ContentRevision contentRevisionBefore,
+ ContentRevision contentRevisionAfter, FileStatus fileStatus,
+ ChangelistBuilder builder, VcsKey vcsKey) {
if (contentRevisionBefore == null && contentRevisionAfter == null) {
return;
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgCurrentBinaryContentRevision.java b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgCurrentBinaryContentRevision.java
index 8be5a7b0a9dd..a11a6c54e0c2 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgCurrentBinaryContentRevision.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgCurrentBinaryContentRevision.java
@@ -14,20 +14,28 @@ package org.zmlx.hg4idea.provider;
import com.intellij.openapi.vcs.changes.CurrentBinaryContentRevision;
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
+import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.zmlx.hg4idea.HgFile;
-final class HgCurrentBinaryContentRevision extends CurrentBinaryContentRevision {
- private VcsRevisionNumber revisionNumber;
+final public class HgCurrentBinaryContentRevision extends CurrentBinaryContentRevision {
+ @NotNull private VcsRevisionNumber myRevisionNumber;
+ @NotNull private VirtualFile myRepositoryRoot;
- HgCurrentBinaryContentRevision(HgFile hgFile, VcsRevisionNumber revisionNumber) {
+ HgCurrentBinaryContentRevision(@NotNull HgFile hgFile, @NotNull VcsRevisionNumber revisionNumber) {
super(hgFile.toFilePath());
- this.revisionNumber = revisionNumber;
+ myRepositoryRoot = hgFile.getRepo();
+ myRevisionNumber = revisionNumber;
}
@NotNull
@Override
public VcsRevisionNumber getRevisionNumber() {
- return revisionNumber;
+ return myRevisionNumber;
+ }
+
+ @NotNull
+ public VirtualFile getRepositoryRoot() {
+ return myRepositoryRoot;
}
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgCurrentContentRevision.java b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgCurrentContentRevision.java
index c6c4bf72710b..3c427d8d7db9 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgCurrentContentRevision.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgCurrentContentRevision.java
@@ -34,7 +34,7 @@ class HgCurrentContentRevision extends CurrentContentRevision {
return revisionNumber;
}
- public static ContentRevision create(@NotNull HgFile hgFile, HgRevisionNumber revision) {
+ public static ContentRevision create(@NotNull HgFile hgFile, @NotNull HgRevisionNumber revision) {
VirtualFile virtualFile = VcsUtil.getVirtualFile(hgFile.getFile());
if (virtualFile == null) {
return null;
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 06b74148156e..509e4f82eaff 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/commit/HgCheckinEnvironment.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/commit/HgCheckinEnvironment.java
@@ -20,21 +20,21 @@ import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.Condition;
import com.intellij.openapi.vcs.CheckinProjectPanel;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.VcsException;
-import com.intellij.openapi.vcs.changes.Change;
-import com.intellij.openapi.vcs.changes.ChangeList;
-import com.intellij.openapi.vcs.changes.ContentRevision;
-import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager;
+import com.intellij.openapi.vcs.changes.*;
import com.intellij.openapi.vcs.checkin.CheckinEnvironment;
import com.intellij.openapi.vcs.ui.RefreshableOnComponent;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.FunctionUtil;
import com.intellij.util.NullableFunction;
import com.intellij.util.PairConsumer;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.UIUtil;
import com.intellij.vcsUtil.VcsUtil;
+import com.intellij.xml.util.XmlStringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.*;
@@ -43,17 +43,23 @@ import org.zmlx.hg4idea.command.*;
import org.zmlx.hg4idea.execution.HgCommandException;
import org.zmlx.hg4idea.execution.HgCommandExecutor;
import org.zmlx.hg4idea.execution.HgCommandResult;
+import org.zmlx.hg4idea.provider.HgCurrentBinaryContentRevision;
import org.zmlx.hg4idea.repo.HgRepository;
-import org.zmlx.hg4idea.repo.HgRepositoryManager;
import org.zmlx.hg4idea.util.HgUtil;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
import java.util.*;
+import java.util.List;
public class HgCheckinEnvironment implements CheckinEnvironment {
private final Project myProject;
private boolean myNextCommitIsPushed;
private boolean myNextCommitAmend; // If true, the next commit is amended
+ private boolean myShouldCommitSubrepos;
public HgCheckinEnvironment(Project project) {
myProject = project;
@@ -83,21 +89,21 @@ public class HgCheckinEnvironment implements CheckinEnvironment {
@NotNull NullableFunction<Object, Object> parametersHolder,
Set<String> feedback) {
List<VcsException> exceptions = new LinkedList<VcsException>();
- Map<VirtualFile, Set<HgFile>> repositoriesMap = getFilesByRepository(changes);
- for (Map.Entry<VirtualFile, Set<HgFile>> entry : repositoriesMap.entrySet()) {
+ Map<HgRepository, Set<HgFile>> repositoriesMap = getFilesByRepository(changes);
+ for (Map.Entry<HgRepository, Set<HgFile>> entry : repositoriesMap.entrySet()) {
- VirtualFile repo = entry.getKey();
+ HgRepository repo = entry.getKey();
Set<HgFile> selectedFiles = entry.getValue();
+ HgCommitCommand command =
+ new HgCommitCommand(myProject, repo.getRoot(), preparedComment, myNextCommitAmend);
- HgCommitCommand command = new HgCommitCommand(myProject, repo, preparedComment, myNextCommitAmend);
-
- if (isMergeCommit(repo)) {
+ if (isMergeCommit(repo.getRoot())) {
//partial commits are not allowed during merges
//verifyResult that all changed files in the repo are selected
//If so, commit the entire repository
//If not, abort
- Set<HgFile> changedFilesNotInCommit = getChangedFilesNotInCommit(repo, selectedFiles);
+ Set<HgFile> changedFilesNotInCommit = getChangedFilesNotInCommit(repo.getRoot(), selectedFiles);
boolean partial = !changedFilesNotInCommit.isEmpty();
@@ -122,6 +128,9 @@ public class HgCheckinEnvironment implements CheckinEnvironment {
// so no need to set the files on the command, because then mercurial will complain
} else {
command.setFiles(selectedFiles);
+ if (myShouldCommitSubrepos && repo.hasSubrepos()) {
+ command.setSubrepos(HgUtil.getNamesWithoutHashes(repo.getSubrepos()));
+ }
}
try {
command.execute();
@@ -134,9 +143,7 @@ public class HgCheckinEnvironment implements CheckinEnvironment {
// push if needed
if (myNextCommitIsPushed && exceptions.isEmpty()) {
- final Set<VirtualFile> preselectedFiles = repositoriesMap.keySet();
- HgRepositoryManager repositoryManager = HgUtil.getRepositoryManager(myProject);
- final List<HgRepository> preselectedRepositories = HgActionUtil.collectRepositoriesFromFiles(repositoryManager, preselectedFiles);
+ final List<HgRepository> preselectedRepositories = ContainerUtil.newArrayList(repositoriesMap.keySet());
UIUtil.invokeLaterIfNeeded(new Runnable() {
public void run() {
new VcsPushDialog(myProject, preselectedRepositories).show();
@@ -154,7 +161,8 @@ public class HgCheckinEnvironment implements CheckinEnvironment {
private Set<HgFile> getChangedFilesNotInCommit(VirtualFile repo, Set<HgFile> selectedFiles) {
List<HgRevisionNumber> parents = new HgWorkingCopyRevisionsCommand(myProject).parents(repo);
- HgStatusCommand statusCommand = new HgStatusCommand.Builder(true).unknown(false).ignored(false).baseRevision(parents.get(0)).build(myProject);
+ HgStatusCommand statusCommand =
+ new HgStatusCommand.Builder(true).unknown(false).ignored(false).baseRevision(parents.get(0)).build(myProject);
Set<HgChange> allChangedFilesInRepo = statusCommand.execute(repo);
Set<HgFile> filesNotIncluded = new HashSet<HgFile>();
@@ -229,29 +237,29 @@ public class HgCheckinEnvironment implements CheckinEnvironment {
}
@NotNull
- private Map<VirtualFile, Set<HgFile>> getFilesByRepository(List<Change> changes) {
- Map<VirtualFile, Set<HgFile>> result = new HashMap<VirtualFile, Set<HgFile>>();
+ private Map<HgRepository, Set<HgFile>> getFilesByRepository(List<Change> changes) {
+ Map<HgRepository, Set<HgFile>> result = new HashMap<HgRepository, Set<HgFile>>();
for (Change change : changes) {
ContentRevision afterRevision = change.getAfterRevision();
ContentRevision beforeRevision = change.getBeforeRevision();
if (afterRevision != null) {
- addFile(result, afterRevision.getFile());
+ addFile(result, afterRevision);
}
if (beforeRevision != null) {
- addFile(result, beforeRevision.getFile());
+ addFile(result, beforeRevision);
}
}
return result;
}
- private void addFile(Map<VirtualFile, Set<HgFile>> result, FilePath filePath) {
- if (filePath == null) {
- return;
- }
-
- VirtualFile repo = VcsUtil.getVcsRootFor(myProject, filePath);
- if (repo == null || filePath.isDirectory()) {
+ private void addFile(Map<HgRepository, Set<HgFile>> result, ContentRevision contentRevision) {
+ FilePath filePath = contentRevision.getFile();
+ // try to find repository from hgFile from change
+ HgRepository repo = HgUtil.getRepositoryForFile(myProject, contentRevision instanceof HgCurrentBinaryContentRevision
+ ? ((HgCurrentBinaryContentRevision)contentRevision).getRepositoryRoot()
+ : ChangesUtil.findValidParentAccurately(filePath));
+ if (repo == null) {
return;
}
@@ -261,7 +269,7 @@ public class HgCheckinEnvironment implements CheckinEnvironment {
result.put(repo, hgFiles);
}
- hgFiles.add(new HgFile(repo, filePath));
+ hgFiles.add(new HgFile(repo.getRoot(), filePath));
}
public void setNextCommitIsPushed() {
@@ -272,27 +280,55 @@ public class HgCheckinEnvironment implements CheckinEnvironment {
* Commit options for hg
*/
private class HgCommitAdditionalComponent extends DvcsCommitAdditionalComponent {
+ @NotNull private final JCheckBox myCommitSubrepos;
public HgCommitAdditionalComponent(@NotNull Project project, @NotNull CheckinProjectPanel panel) {
super(project, panel);
HgVcs myVcs = HgVcs.getInstance(myProject);
myAmend.setEnabled(myVcs != null && myVcs.getVersion().isAmendSupported());
+ final Insets insets = new Insets(2, 2, 2, 2);
+ // add commit subrepos checkbox
+ GridBagConstraints c = new GridBagConstraints();
+ c.anchor = GridBagConstraints.CENTER;
+ c.insets = insets;
+ c.gridx = 1;
+ c.gridy = 2;
+ c.weightx = 1;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ myCommitSubrepos = new JCheckBox("Commit subrepositories", false);
+ myCommitSubrepos.setToolTipText(XmlStringUtil.wrapInHtml(
+ "Commit all subrepos for selected repositories.<br>" +
+ " <code>hg ci <i><b>files</b></i> -S <i><b>subrepos</b></i></code>"));
+ myCommitSubrepos.setMnemonic('s');
+ myPanel.add(myCommitSubrepos, c);
+ Collection<HgRepository> repos =
+ HgActionUtil.collectRepositoriesFromFiles(HgUtil.getRepositoryManager(myProject), myCheckinPanel.getRoots());
+ myCommitSubrepos.setVisible(ContainerUtil.exists(repos, new Condition<HgRepository>() {
+ @Override
+ public boolean value(HgRepository repository) {
+ return repository.hasSubrepos();
+ }
+ }));
+ myCommitSubrepos.addActionListener(new MySelectionListener(myAmend));
+ myAmend.addActionListener(new MySelectionListener(myCommitSubrepos));
}
@Override
public void refresh() {
super.refresh();
- myNextCommitAmend = false;
+ restoreState();
}
@Override
public void saveState() {
myNextCommitAmend = myAmend.isSelected();
+ myShouldCommitSubrepos = myCommitSubrepos.isSelected();
}
@Override
public void restoreState() {
myNextCommitAmend = false;
+ myShouldCommitSubrepos = false;
}
@NotNull
@@ -313,5 +349,25 @@ public class HgCheckinEnvironment implements CheckinEnvironment {
HgCommandResult result = commandExecutor.executeInCurrentThread(repo, "log", args);
return result == null ? "" : result.getRawOutput();
}
+
+ private class MySelectionListener implements ActionListener {
+ JCheckBox myUnselectedComponent;
+
+ public MySelectionListener(JCheckBox unselectedComponent) {
+ myUnselectedComponent = unselectedComponent;
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ JCheckBox source = (JCheckBox)e.getSource();
+ if (source.isSelected()) {
+ myUnselectedComponent.setSelected(false);
+ myUnselectedComponent.setEnabled(false);
+ }
+ else{
+ myUnselectedComponent.setEnabled(true);
+ }
+ }
+ }
}
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPushSupport.java b/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPushSupport.java
index 13f4aaa08f6a..af584d52c32c 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPushSupport.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPushSupport.java
@@ -15,28 +15,19 @@
*/
package org.zmlx.hg4idea.push;
-import com.intellij.dvcs.DvcsUtil;
import com.intellij.dvcs.push.*;
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.ui.SimpleColoredText;
-import com.intellij.ui.SimpleTextAttributes;
-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.List;
-
public class HgPushSupport extends PushSupport<HgRepository, HgPushSource, HgTarget> {
- private final static String ENTER_REMOTE = "Enter Remote";
@NotNull private final Project myProject;
@NotNull private final HgVcs myVcs;
@@ -72,28 +63,11 @@ public class HgPushSupport extends PushSupport<HgRepository, HgPushSource, HgTar
@NotNull
@Override
- public List<String> getTargetNames(@NotNull HgRepository repository) {
- return ContainerUtil.sorted(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);
+ String localBranch = repository.getCurrentBranchName();
return new HgPushSource(localBranch);
}
- @Override
- @NotNull
- public HgTarget createTarget(@NotNull HgRepository repository, @NotNull String targetName) {
- return new HgTarget(targetName);
- }
-
@NotNull
@Override
public RepositoryManager<HgRepository> getRepositoryManager() {
@@ -106,18 +80,8 @@ public class HgPushSupport extends PushSupport<HgRepository, HgPushSource, HgTar
}
@Override
- @Nullable
- public VcsError validate(@NotNull HgRepository repository, @Nullable String targetToValidate) {
- return StringUtil.isEmptyOrSpaces(targetToValidate)
- ? VcsError.createEmptyTargetError(DvcsUtil.getShortRepositoryName(repository))
- : null;
- }
-
- @Override
- public SimpleColoredText renderTarget(@Nullable HgTarget target) {
- if (target == null || StringUtil.isEmptyOrSpaces(target.getPresentation())) {
- return new SimpleColoredText(ENTER_REMOTE, SimpleTextAttributes.GRAY_ITALIC_ATTRIBUTES);
- }
- return new SimpleColoredText(target.getPresentation(), SimpleTextAttributes.SYNTHETIC_ATTRIBUTES);
+ @NotNull
+ public PushTargetPanel<HgTarget> createTargetPanel(@NotNull HgRepository repository, @Nullable HgTarget defaultTarget) {
+ return new HgPushTargetPanel(repository, defaultTarget);
}
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPushTargetPanel.java b/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPushTargetPanel.java
new file mode 100644
index 000000000000..e3d02ea4e3fb
--- /dev/null
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgPushTargetPanel.java
@@ -0,0 +1,88 @@
+/*
+ * 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.DvcsUtil;
+import com.intellij.dvcs.push.PushTargetPanel;
+import com.intellij.dvcs.push.VcsError;
+import com.intellij.openapi.ui.ValidationInfo;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.ui.ColoredTreeCellRenderer;
+import com.intellij.ui.SimpleTextAttributes;
+import com.intellij.ui.TextFieldWithAutoCompletion;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.zmlx.hg4idea.repo.HgRepository;
+import org.zmlx.hg4idea.util.HgUtil;
+
+import java.awt.*;
+import java.util.List;
+
+public class HgPushTargetPanel extends PushTargetPanel<HgTarget> {
+
+ private final static String ENTER_REMOTE = "Enter Remote";
+ private final HgRepository myRepository;
+ private final TextFieldWithAutoCompletion<String> myDestTargetPanel;
+ private String myOldText;
+
+ public HgPushTargetPanel(@NotNull HgRepository repository, @Nullable HgTarget defaultTarget) {
+ setLayout(new BorderLayout());
+ setOpaque(false);
+ myRepository = repository;
+ final List<String> targetVariants = HgUtil.getTargetNames(repository);
+ myOldText = defaultTarget != null ? defaultTarget.getPresentation() : "";
+ myDestTargetPanel = new PushTargetTextField(repository.getProject(), targetVariants, myOldText);
+ add(myDestTargetPanel, BorderLayout.CENTER);
+ }
+
+ @Override
+ public void render(@NotNull ColoredTreeCellRenderer renderer) {
+ String targetText = myDestTargetPanel.getText();
+ if (StringUtil.isEmptyOrSpaces(targetText)) {
+ renderer.append(ENTER_REMOTE, SimpleTextAttributes.GRAY_ITALIC_ATTRIBUTES, this);
+ }
+ renderer.append(targetText, SimpleTextAttributes.SYNTHETIC_ATTRIBUTES, this);
+ }
+
+ @Override
+ @NotNull
+ public HgTarget getValue() {
+ return createValidPushTarget();
+ }
+
+ @NotNull
+ private HgTarget createValidPushTarget() {
+ return new HgTarget(myDestTargetPanel.getText());
+ }
+
+ @Override
+ public void fireOnCancel() {
+ myDestTargetPanel.setText(myOldText);
+ }
+
+ @Override
+ public void fireOnChange() {
+ myOldText = myDestTargetPanel.getText();
+ }
+
+ @Nullable
+ public ValidationInfo verify() {
+ if (StringUtil.isEmptyOrSpaces(myDestTargetPanel.getText())) {
+ return new ValidationInfo(VcsError.createEmptyTargetError(DvcsUtil.getShortRepositoryName(myRepository)).getText(), this);
+ }
+ return null;
+ }
+}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgTarget.java b/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgTarget.java
index 8f5aca3838ca..87a5d3bf321e 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgTarget.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/push/HgTarget.java
@@ -26,7 +26,6 @@ public class HgTarget implements PushTarget {
myTarget = name;
}
- @Override
@NotNull
public String getPresentation() {
return HgUtil.removePasswordIfNeeded(myTarget);
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/push/PushTargetTextField.java b/plugins/hg4idea/src/org/zmlx/hg4idea/push/PushTargetTextField.java
new file mode 100644
index 000000000000..c05cb9133121
--- /dev/null
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/push/PushTargetTextField.java
@@ -0,0 +1,63 @@
+/*
+ * 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.openapi.editor.ex.EditorEx;
+import com.intellij.openapi.project.Project;
+import com.intellij.ui.TextFieldWithAutoCompletion;
+import com.intellij.ui.TextFieldWithAutoCompletionListProvider;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NotNull;
+
+import java.awt.event.FocusAdapter;
+import java.awt.event.FocusEvent;
+import java.util.List;
+
+public class PushTargetTextField extends TextFieldWithAutoCompletion<String> {
+
+ public PushTargetTextField(@NotNull Project project, @NotNull final List<String> targetVariants, @NotNull String defaultTargetName) {
+ super(project, getCompletionProvider(targetVariants), true, defaultTargetName);
+ setBorder(UIUtil.getTableFocusCellHighlightBorder());
+ setOneLineMode(true);
+ addFocusListener(new FocusAdapter() {
+ @Override
+ public void focusGained(FocusEvent e) {
+ selectAll();
+ }
+ });
+ }
+
+ @Override
+ public boolean shouldHaveBorder() {
+ return false;
+ }
+
+ @Override
+ protected void updateBorder(@NotNull final EditorEx editor) {
+ }
+
+ @NotNull
+ private static TextFieldWithAutoCompletionListProvider<String> getCompletionProvider(@NotNull final List<String> targetVariants) {
+ return new StringsCompletionProvider(targetVariants, null) {
+ @Override
+ public int compare(String item1, String item2) {
+ return Integer.valueOf(ContainerUtil.indexOf(targetVariants, item1)).compareTo(ContainerUtil.indexOf(targetVariants, item2));
+ }
+ };
+ }
+
+}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepoInfo.java b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepoInfo.java
index f73375f9c791..55efa0b43418 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepoInfo.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepoInfo.java
@@ -34,6 +34,7 @@ public class HgRepoInfo {
@NotNull private Set<HgNameWithHashInfo> myBookmarks = Collections.emptySet();
@NotNull private Set<HgNameWithHashInfo> myTags = Collections.emptySet();
@NotNull private Set<HgNameWithHashInfo> myLocalTags = Collections.emptySet();
+ @NotNull Set<HgNameWithHashInfo> mySubrepos = Collections.emptySet();
public HgRepoInfo(@NotNull String currentBranch,
@Nullable String currentRevision,
@@ -43,7 +44,7 @@ public class HgRepoInfo {
@NotNull Collection<HgNameWithHashInfo> bookmarks,
@Nullable String currentBookmark,
@NotNull Collection<HgNameWithHashInfo> tags,
- @NotNull Collection<HgNameWithHashInfo> localTags) {
+ @NotNull Collection<HgNameWithHashInfo> localTags, @NotNull Collection<HgNameWithHashInfo> subrepos) {
myCurrentBranch = currentBranch;
myCurrentRevision = currentRevision;
myTipRevision = currentTipRevision;
@@ -53,6 +54,7 @@ public class HgRepoInfo {
myCurrentBookmark = currentBookmark;
myTags = new LinkedHashSet<HgNameWithHashInfo>(tags);
myLocalTags = new LinkedHashSet<HgNameWithHashInfo>(localTags);
+ mySubrepos = new HashSet<HgNameWithHashInfo>(subrepos);
}
@NotNull
@@ -116,6 +118,7 @@ public class HgRepoInfo {
if (!myBookmarks.equals(info.myBookmarks)) return false;
if (!myTags.equals(info.myTags)) return false;
if (!myLocalTags.equals(info.myLocalTags)) return false;
+ if (!mySubrepos.equals(info.mySubrepos)) return false;
return true;
}
@@ -123,7 +126,7 @@ public class HgRepoInfo {
@Override
public int hashCode() {
return Objects.hashCode(myCurrentBranch, myCurrentRevision, myTipRevision, myCurrentBookmark, myState, myBranches, myBookmarks, myTags,
- myLocalTags);
+ myLocalTags, mySubrepos);
}
@Override
@@ -132,4 +135,13 @@ public class HgRepoInfo {
return String.format("HgRepository{myCurrentBranch=%s, myCurrentRevision='%s', myState=%s}",
myCurrentBranch, myCurrentRevision, myState);
}
+
+ public boolean hasSubrepos() {
+ return !mySubrepos.isEmpty();
+ }
+
+ @NotNull
+ public Collection<HgNameWithHashInfo> getSubrepos() {
+ return mySubrepos;
+ }
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepository.java b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepository.java
index 8a5c4fc81e53..8d3b66f0ba54 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepository.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepository.java
@@ -71,5 +71,10 @@ public interface HgRepository extends Repository {
@NotNull
HgConfig getRepositoryConfig();
+ boolean hasSubrepos();
+
+ @NotNull
+ Collection<HgNameWithHashInfo> getSubrepos();
+
void updateConfig();
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java
index b670fb056c0c..6203f259b9bc 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.util.text.StringUtil;
import com.intellij.openapi.vcs.AbstractVcs;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
@@ -99,6 +100,19 @@ public class HgRepositoryImpl extends RepositoryImpl implements HgRepository {
@Nullable
@Override
+ /**
+ * Return active bookmark name if exist or heavy branch name otherwise
+ */
+ public String getCurrentBranchName() {
+ String branchOrBookMarkName = getCurrentBookmark();
+ if (StringUtil.isEmptyOrSpaces(branchOrBookMarkName)) {
+ branchOrBookMarkName = getCurrentBranch();
+ }
+ return branchOrBookMarkName;
+ }
+
+ @Nullable
+ @Override
public AbstractVcs getVcs() {
return HgVcs.getInstance(getProject());
}
@@ -163,6 +177,16 @@ public class HgRepositoryImpl extends RepositoryImpl implements HgRepository {
}
@Override
+ public boolean hasSubrepos() {
+ return myInfo.hasSubrepos();
+ }
+
+ @NotNull
+ public Collection<HgNameWithHashInfo> getSubrepos() {
+ return myInfo.getSubrepos();
+ }
+
+ @Override
public boolean isFresh() {
return myIsFresh;
}
@@ -199,7 +223,8 @@ public class HgRepositoryImpl extends RepositoryImpl implements HgRepository {
return
new HgRepoInfo(myReader.readCurrentBranch(), myReader.readCurrentRevision(), myReader.readCurrentTipRevision(), myReader.readState(),
myReader.readBranches(),
- myReader.readBookmarks(), myReader.readCurrentBookmark(), myReader.readTags(), myReader.readLocalTags());
+ myReader.readBookmarks(), myReader.readCurrentBookmark(), myReader.readTags(), myReader.readLocalTags(),
+ myReader.readSubrepos());
}
public void updateConfig() {
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryReader.java b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryReader.java
index 923087d0b3b2..fab661a99a32 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryReader.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryReader.java
@@ -48,10 +48,10 @@ public class HgRepositoryReader {
private static Pattern HASH_NAME = Pattern.compile("\\s*([0-9a-fA-F]+)\\s+(.+)");
private static Pattern HASH_STATUS_NAME = Pattern.compile("\\s*([0-9a-fA-F]+)\\s+\\w\\s+(.+)");
- //hash + name_or_revision_num; hash + status_character + name_or_revision_num
+ //hash + name_or_revision_num; hash + status_character + name_or_revision_num
@NotNull private final File myHgDir; // .hg
- @NotNull private File myBranchHeadsFile; // .hg/cache/branch* + part depends on version
+ @NotNull private File myBranchHeadsFile; // .hg/cache/branch* + part depends on version
@NotNull private final File myCacheDir; // .hg/cache (does not exist before first commit)
@NotNull private final File myCurrentBranch; // .hg/branch
@NotNull private final File myBookmarksFile; //.hg/bookmarks
@@ -59,6 +59,8 @@ public class HgRepositoryReader {
@NotNull private final File myTagsFile; //.hgtags - not in .hg directory!!!
@NotNull private final File myLocalTagsFile; // .hg/localtags
@NotNull private final File myDirStateFile; // .hg/dirstate
+ @NotNull private final File mySubrepoFile; // .hgsubstate
+
@NotNull private final VcsLogObjectsFactory myVcsObjectsFactory;
private final boolean myStatusInBranchFile;
@NotNull final HgVcs myVcs;
@@ -76,6 +78,7 @@ public class HgRepositoryReader {
myCurrentBookmark = new File(myHgDir, "bookmarks.current");
myLocalTagsFile = new File(myHgDir, "localtags");
myTagsFile = new File(myHgDir.getParentFile(), ".hgtags");
+ mySubrepoFile = new File(myHgDir.getParentFile(), ".hgsubstate");
myDirStateFile = new File(myHgDir, "dirstate");
myVcsObjectsFactory = ServiceManager.getService(vcs.getProject(), VcsLogObjectsFactory.class);
}
@@ -192,6 +195,10 @@ public class HgRepositoryReader {
return new File(myHgDir, "merge").exists();
}
+ public boolean hasSubrepos() {
+ return mySubrepoFile.exists();
+ }
+
public boolean isRebaseInProgress() {
return new File(myHgDir, "rebasestate").exists();
}
@@ -248,4 +255,11 @@ public class HgRepositoryReader {
public String readCurrentBookmark() {
return myCurrentBookmark.exists() ? RepositoryUtil.tryLoadFile(myCurrentBookmark) : null;
}
+
+ @NotNull
+ public Collection<HgNameWithHashInfo> readSubrepos() {
+ if (!hasSubrepos()) return Collections.emptySet();
+ return readReference(mySubrepoFile);
+ }
+
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/status/ui/HgStatusWidget.java b/plugins/hg4idea/src/org/zmlx/hg4idea/status/ui/HgStatusWidget.java
index 05a62338a9ce..9c89e74f8759 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/status/ui/HgStatusWidget.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/status/ui/HgStatusWidget.java
@@ -32,7 +32,7 @@ import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.HgProjectSettings;
import org.zmlx.hg4idea.HgUpdater;
import org.zmlx.hg4idea.HgVcs;
-import org.zmlx.hg4idea.action.HgBranchPopup;
+import org.zmlx.hg4idea.branch.HgBranchPopup;
import org.zmlx.hg4idea.repo.HgRepository;
import org.zmlx.hg4idea.util.HgUtil;
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgConfigurationProjectPanel.form b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgConfigurationProjectPanel.form
index 38dc6eb52908..cc1ea793d2c7 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgConfigurationProjectPanel.form
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgConfigurationProjectPanel.form
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.zmlx.hg4idea.ui.HgConfigurationProjectPanel">
- <grid id="27dc6" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <grid id="27dc6" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
- <xy x="20" y="20" width="623" height="228"/>
+ <xy x="20" y="20" width="623" height="299"/>
</constraints>
<properties/>
<border type="none"/>
@@ -11,7 +11,7 @@
<grid id="8c1f" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
- <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="8" fill="2" indent="0" use-parent-layout="false"/>
+ <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="8" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<clientProperties>
@@ -39,16 +39,43 @@
</component>
</children>
</grid>
+ <vspacer id="4088f">
+ <constraints>
+ <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+ </constraints>
+ </vspacer>
+ <grid id="c2117" binding="myRepositorySettingsPanel" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <margin top="0" left="0" bottom="0" right="0"/>
+ <constraints>
+ <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="8" fill="2" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties/>
+ <clientProperties>
+ <BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithIndent"/>
+ </clientProperties>
+ <border type="etched" title="Repository Settings"/>
+ <children>
+ <component id="fadf2" class="com.intellij.ui.components.JBCheckBox" binding="mySyncBranchControl">
+ <constraints>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text value="Control &amp;branches from different roots synchronously"/>
+ <toolTipText value="If selected, you would be able to checkout, compare, delete and create new branches in all Git roots with a single action"/>
+ </properties>
+ </component>
+ </children>
+ </grid>
<grid id="4e3f3" layout-manager="GridLayoutManager" row-count="1" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
- <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<clientProperties>
<BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithIndent"/>
</clientProperties>
- <border type="etched" title="Path to hg executable"/>
+ <border type="none"/>
<children>
<component id="83ec6" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="myPathSelector" custom-create="true">
<constraints>
@@ -65,7 +92,7 @@
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
- <text value="&amp;Specify executable path"/>
+ <text value="&amp;Path to hg executable"/>
</properties>
</component>
<component id="61549" class="javax.swing.JButton" binding="myTestButton">
@@ -80,11 +107,6 @@
</component>
</children>
</grid>
- <vspacer id="4088f">
- <constraints>
- <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
- </constraints>
- </vspacer>
</children>
</grid>
<buttonGroups>
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgConfigurationProjectPanel.java b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgConfigurationProjectPanel.java
index 2aff9073d266..619536de0f88 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgConfigurationProjectPanel.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/ui/HgConfigurationProjectPanel.java
@@ -12,14 +12,18 @@
// limitations under the License.
package org.zmlx.hg4idea.ui;
+import com.intellij.dvcs.branch.DvcsBranchSync;
+import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
+import com.intellij.ui.components.JBCheckBox;
import org.jetbrains.annotations.NotNull;
import org.zmlx.hg4idea.HgProjectSettings;
import org.zmlx.hg4idea.HgVcs;
import org.zmlx.hg4idea.HgVcsMessages;
+import org.zmlx.hg4idea.repo.HgRepositoryManager;
import org.zmlx.hg4idea.util.HgUtil;
import org.zmlx.hg4idea.util.HgVersion;
@@ -36,6 +40,8 @@ public class HgConfigurationProjectPanel {
private JCheckBox myIgnoredWhitespacesInAnnotationsCbx;
private TextFieldWithBrowseButton myPathSelector;
private JButton myTestButton;
+ private JBCheckBox mySyncBranchControl;
+ private JPanel myRepositorySettingsPanel;
private final HgVcs myVcs;
public HgConfigurationProjectPanel(@NotNull HgProjectSettings projectSettings, @NotNull Project project) {
@@ -58,12 +64,15 @@ public class HgConfigurationProjectPanel {
);
}
});
+ final HgRepositoryManager repositoryManager = ServiceManager.getService(project, HgRepositoryManager.class);
+ myRepositorySettingsPanel.setVisible(repositoryManager != null && repositoryManager.moreThanOneRoot());
}
public boolean isModified() {
boolean executableModified = !getCurrentPath().equals(myProjectSettings.getHgExecutable());
return executableModified ||
myCheckIncomingOutgoingCbx.isSelected() != myProjectSettings.isCheckIncomingOutgoing() ||
+ ((myProjectSettings.getSyncSetting() == DvcsBranchSync.SYNC) != mySyncBranchControl.isSelected()) ||
myIgnoredWhitespacesInAnnotationsCbx.isSelected() != myProjectSettings.isWhitespacesIgnoredInAnnotations();
}
@@ -71,6 +80,7 @@ public class HgConfigurationProjectPanel {
myProjectSettings.setCheckIncomingOutgoing(myCheckIncomingOutgoingCbx.isSelected());
myProjectSettings.setIgnoreWhitespacesInAnnotations(myIgnoredWhitespacesInAnnotationsCbx.isSelected());
myProjectSettings.setHgExecutable(getCurrentPath());
+ myProjectSettings.setSyncSetting(mySyncBranchControl.isSelected() ? DvcsBranchSync.SYNC : DvcsBranchSync.DONT);
myVcs.checkVersion();
}
@@ -82,6 +92,7 @@ public class HgConfigurationProjectPanel {
myCheckIncomingOutgoingCbx.setSelected(myProjectSettings.isCheckIncomingOutgoing());
myIgnoredWhitespacesInAnnotationsCbx.setSelected(myProjectSettings.isWhitespacesIgnoredInAnnotations());
myPathSelector.setText(myProjectSettings.getGlobalSettings().getHgExecutable());
+ mySyncBranchControl.setSelected(myProjectSettings.getSyncSetting() == DvcsBranchSync.SYNC);
}
public JPanel getPanel() {
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java
index 3bb14721f0a8..fcf275f70703 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java
@@ -41,6 +41,7 @@ import com.intellij.openapi.wm.StatusBar;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.openapi.wm.impl.status.StatusBarUtil;
import com.intellij.ui.GuiUtils;
+import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.vcsUtil.VcsUtil;
import org.jetbrains.annotations.NotNull;
@@ -584,16 +585,7 @@ 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 branchOrBookMarkName;
+ return branchText + repository.getCurrentBranchName();
}
@NotNull
@@ -716,4 +708,14 @@ public abstract class HgUtil {
}
return Couple.of(userName, email);
}
+
+ @NotNull
+ public static List<String> getTargetNames(@NotNull HgRepository repository) {
+ return ContainerUtil.sorted(ContainerUtil.map(repository.getRepositoryConfig().getPaths(), new Function<String, String>() {
+ @Override
+ public String fun(String s) {
+ return removePasswordIfNeeded(s);
+ }
+ }));
+ }
}