diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/HgNameWithHashInfo.java b/plugins/hg4idea/src/org/zmlx/hg4idea/HgNameWithHashInfo.java
index d7e09babe7a0..ccc87f690ac4 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/HgNameWithHashInfo.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/HgNameWithHashInfo.java
@@ -38,11 +38,11 @@ public class HgNameWithHashInfo {
}
/**
- *
Returns the hash on which this branch or bookmark or tag is reference to.
+ * Returns the hash on which this bookmark or tag is reference to.
*/
@NotNull
- public String getHash() {
- return myHash.asString();
+ public Hash getHash() {
+ return myHash;
}
@NotNull
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopupActions.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopupActions.java
index 0e3142841f9f..4198069bad05 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopupActions.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchPopupActions.java
@@ -16,11 +16,13 @@
package org.zmlx.hg4idea.action;
import com.intellij.dvcs.DvcsUtil;
+import com.intellij.dvcs.repo.Repository;
import com.intellij.dvcs.ui.NewBranchAction;
import com.intellij.openapi.actionSystem.ActionGroup;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.DumbAwareAction;
@@ -28,16 +30,18 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.update.UpdatedFiles;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.Function;
import com.intellij.util.PlatformIcons;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.vcs.log.Hash;
+import com.intellij.vcs.log.impl.HashImpl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.zmlx.hg4idea.HgNameWithHashInfo;
import org.zmlx.hg4idea.HgRevisionNumber;
import org.zmlx.hg4idea.HgVcs;
import org.zmlx.hg4idea.HgVcsMessages;
-import org.zmlx.hg4idea.command.HgBookmarkCreateCommand;
-import org.zmlx.hg4idea.command.HgBranchCreateCommand;
-import org.zmlx.hg4idea.command.HgMergeCommand;
-import org.zmlx.hg4idea.command.HgUpdateCommand;
+import org.zmlx.hg4idea.command.*;
import org.zmlx.hg4idea.execution.HgCommandException;
import org.zmlx.hg4idea.execution.HgCommandResult;
import org.zmlx.hg4idea.execution.HgCommandResultHandler;
@@ -48,8 +52,7 @@ import org.zmlx.hg4idea.ui.HgBookmarkDialog;
import org.zmlx.hg4idea.util.HgErrorUtil;
import org.zmlx.hg4idea.util.HgUtil;
-import java.util.Collections;
-import java.util.List;
+import java.util.*;
/**
* @author Nadya Zabrodina
@@ -68,7 +71,7 @@ public class HgBranchPopupActions {
DefaultActionGroup popupGroup = new DefaultActionGroup(null, false);
popupGroup.addAction(new HgNewBranchAction(myProject, Collections.singletonList(myRepository), myRepository.getRoot()));
popupGroup.addAction(new HgNewBookmarkAction(myProject, Collections.singletonList(myRepository), myRepository.getRoot()));
-
+ popupGroup.addAction(new HgShowUnnamedHeadsForCurrentBranchAction(myProject, myRepository));
if (toInsert != null) {
popupGroup.addAll(toInsert);
}
@@ -86,9 +89,9 @@ public class HgBranchPopupActions {
}
popupGroup.addSeparator("Branches");
- List branchNames = HgUtil.getNamesWithoutHashes(myRepository.getBranches());
- Collections.sort(branchNames);
- for (String branch : branchNames) {
+ List branchNamesList = new ArrayList(myRepository.getBranches().keySet());
+ Collections.sort(branchNamesList);
+ for (String branch : branchNamesList) {
if (!branch.equals(myRepository.getCurrentBranch())) { // don't show current branch in the list
popupGroup.add(new BranchActions(myProject, branch, myRepository));
}
@@ -175,6 +178,73 @@ public class HgBranchPopupActions {
}
}
+ static private class HgShowUnnamedHeadsForCurrentBranchAction extends ActionGroup {
+ @NotNull final Project myProject;
+ @NotNull final HgRepository myRepository;
+ @NotNull final String myCurrentBranchName;
+ @NotNull Collection myHeads = new HashSet();
+
+ public HgShowUnnamedHeadsForCurrentBranchAction(@NotNull Project project,
+ @NotNull HgRepository repository) {
+ super(null, true);
+ myProject = project;
+ myRepository = repository;
+ myCurrentBranchName = repository.getCurrentBranch();
+ getTemplatePresentation().setText(String.format("Unnamed heads for %s", myCurrentBranchName));
+ ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
+ @Override
+ public void run() {
+ myHeads = filterUnnamedHeads();
+ }
+ });
+ }
+
+ @NotNull
+ private Collection filterUnnamedHeads() {
+ Collection branchWithHashes = myRepository.getBranches().get(myCurrentBranchName);
+ if (branchWithHashes == null) {
+ // repository is fresh or branch is fresh.
+ return Collections.emptySet();
+ }
+ else {
+ List parents = new HgWorkingCopyRevisionsCommand(myProject).parents(myRepository.getRoot());
+ if (parents.size() == 1) {
+ Collection bookmarkHashes = ContainerUtil.map(myRepository.getBookmarks(), new Function() {
+
+ @Override
+ public Hash fun(HgNameWithHashInfo info) {
+ return info.getHash();
+ }
+ });
+ branchWithHashes.removeAll(bookmarkHashes);
+ branchWithHashes.remove(HashImpl.build(parents.get(0).getChangeset()));
+ }
+ }
+ return branchWithHashes;
+ }
+
+ @NotNull
+ @Override
+ public AnAction[] getChildren(@Nullable AnActionEvent e) {
+ List branchHeadActions = new ArrayList();
+ for (Hash hash : myHeads) {
+ branchHeadActions.add(new BranchActions(myProject, hash.toShortString(), myRepository));
+ }
+ return ContainerUtil.toArray(branchHeadActions, new AnAction[branchHeadActions.size()]);
+ }
+
+ @Override
+ public void update(final AnActionEvent e) {
+ if (myRepository.isFresh()) {
+ e.getPresentation().setEnabled(false);
+ e.getPresentation().setDescription("Checkout of a new branch is not possible before the first commit.");
+ }
+ else if (Repository.State.MERGING.equals(myRepository.getState())) {
+ e.getPresentation().setEnabled(false);
+ }
+ }
+ }
+
/**
* Actions available for branches.
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgLogProvider.java b/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgLogProvider.java
index fb3f17d34a63..13d6e8c9edc1 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgLogProvider.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgLogProvider.java
@@ -103,18 +103,22 @@ public class HgLogProvider implements VcsLogProvider {
}
repository.update();
- Collection branches = repository.getBranches();
+ Map> branches = repository.getBranches();
Collection bookmarks = repository.getBookmarks();
Collection tags = repository.getTags();
Collection localTags = repository.getLocalTags();
Collection refs = new ArrayList(branches.size() + bookmarks.size());
- for (HgNameWithHashInfo branchInfo : branches) {
- refs.add(myVcsObjectsFactory.createRef(myVcsObjectsFactory.createHash(branchInfo.getHash()), branchInfo.getName(), HgRefManager.BRANCH, root));
+ for (Map.Entry> entry : branches.entrySet()) {
+ String branchName = entry.getKey();
+ for (Hash hash : entry.getValue()) {
+ refs.add(myVcsObjectsFactory.createRef(hash, branchName, HgRefManager.BRANCH, root));
+ }
}
+
for (HgNameWithHashInfo bookmarkInfo : bookmarks) {
- refs.add(myVcsObjectsFactory.createRef(myVcsObjectsFactory.createHash(bookmarkInfo.getHash()), bookmarkInfo.getName(),
+ refs.add(myVcsObjectsFactory.createRef(bookmarkInfo.getHash(), bookmarkInfo.getName(),
HgRefManager.BOOKMARK, root));
}
String currentRevision = repository.getCurrentRevision();
@@ -122,10 +126,10 @@ public class HgLogProvider implements VcsLogProvider {
refs.add(myVcsObjectsFactory.createRef(myVcsObjectsFactory.createHash(currentRevision), "tip", HgRefManager.HEAD, root));
}
for (HgNameWithHashInfo tagInfo : tags) {
- refs.add(myVcsObjectsFactory.createRef(myVcsObjectsFactory.createHash(tagInfo.getHash()), tagInfo.getName(), HgRefManager.TAG, root));
+ refs.add(myVcsObjectsFactory.createRef(tagInfo.getHash(), tagInfo.getName(), HgRefManager.TAG, root));
}
for (HgNameWithHashInfo localTagInfo : localTags) {
- refs.add(myVcsObjectsFactory.createRef(myVcsObjectsFactory.createHash(localTagInfo.getHash()), localTagInfo.getName(),
+ refs.add(myVcsObjectsFactory.createRef(localTagInfo.getHash(), localTagInfo.getName(),
HgRefManager.LOCAL_TAG, root));
}
return refs;
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepoInfo.java b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepoInfo.java
index 90c59372dc8e..133bfc7ce869 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepoInfo.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepoInfo.java
@@ -17,14 +17,12 @@ package org.zmlx.hg4idea.repo;
import com.google.common.base.Objects;
import com.intellij.dvcs.repo.Repository;
+import com.intellij.vcs.log.Hash;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.HgNameWithHashInfo;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.LinkedHashSet;
-import java.util.Set;
+import java.util.*;
/**
* @author Nadya Zabrodina
@@ -34,7 +32,7 @@ public class HgRepoInfo {
@Nullable private final String myCurrentRevision;
@NotNull private final Repository.State myState;
@Nullable private String myCurrentBookmark = null;
- @NotNull private Set myBranches = Collections.emptySet();
+ @NotNull private Map> myBranches = Collections.emptyMap();
@NotNull private Set myBookmarks = Collections.emptySet();
@NotNull private Set myTags = Collections.emptySet();
@NotNull private Set myLocalTags = Collections.emptySet();
@@ -42,7 +40,7 @@ public class HgRepoInfo {
public HgRepoInfo(@NotNull String currentBranch,
@Nullable String currentRevision,
@NotNull Repository.State state,
- @NotNull Collection branches,
+ @NotNull Map> branches,
@NotNull Collection bookmarks,
@Nullable String currentBookmark,
@NotNull Collection tags,
@@ -50,7 +48,7 @@ public class HgRepoInfo {
myCurrentBranch = currentBranch;
myCurrentRevision = currentRevision;
myState = state;
- myBranches = new LinkedHashSet(branches);
+ myBranches = branches;
myBookmarks = new LinkedHashSet(bookmarks);
myCurrentBookmark = currentBookmark;
myTags = new LinkedHashSet(tags);
@@ -63,7 +61,7 @@ public class HgRepoInfo {
}
@NotNull
- public Collection getBranches() {
+ public Map> getBranches() {
return myBranches;
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepository.java b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepository.java
index fbaaa4f14a94..c698d50efaab 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepository.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepository.java
@@ -18,11 +18,14 @@ package org.zmlx.hg4idea.repo;
import com.intellij.dvcs.repo.Repository;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.vcs.log.Hash;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.HgNameWithHashInfo;
import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
public interface HgRepository extends Repository {
@@ -38,8 +41,11 @@ public interface HgRepository extends Repository {
@NotNull
String getCurrentBranch();
+ /**
+ * @return map with heavy branch names and appropriate set of head hashes
+ */
@NotNull
- Collection getBranches();
+ Map> getBranches();
@NotNull
Collection getBookmarks();
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java
index c95eb59a4449..db616ee6215c 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryImpl.java
@@ -22,6 +22,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.vcs.log.Hash;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.HgNameWithHashInfo;
@@ -29,6 +30,8 @@ import org.zmlx.hg4idea.HgVcs;
import org.zmlx.hg4idea.util.HgUtil;
import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
/**
@@ -96,7 +99,7 @@ public class HgRepositoryImpl extends RepositoryImpl implements HgRepository {
@Override
@NotNull
- public Collection getBranches() {
+ public Map> getBranches() {
return myInfo.getBranches();
}
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryReader.java b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryReader.java
index bed74806135c..1552b393a478 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryReader.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/repo/HgRepositoryReader.java
@@ -20,6 +20,7 @@ import com.intellij.dvcs.repo.Repository;
import com.intellij.dvcs.repo.RepositoryUtil;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
+import com.intellij.vcs.log.Hash;
import com.intellij.vcs.log.VcsLogObjectsFactory;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -110,8 +111,8 @@ public class HgRepositoryReader {
}
@NotNull
- public Collection readBranches() {
- List branches = new ArrayList();
+ public Map> readBranches() {
+ Map> branchesWithHashes = new HashMap>();
// Set branchNames = new HashSet();
if (isBranchInfoAvailable()) {
String[] branchesWithHeads = RepositoryUtil.tryLoadFile(myBranchHeadsFile).split("\n");
@@ -120,13 +121,18 @@ public class HgRepositoryReader {
Matcher matcher = HASH_NAME.matcher(branchesWithHeads[i]);
if (matcher.matches()) {
String name = matcher.group(2);
- // if (branchNames.add(name)) {
- branches.add(new HgNameWithHashInfo(name, myVcsObjectsFactory.createHash(matcher.group(1))));
- //}
+ if (branchesWithHashes.containsKey(name)) {
+ branchesWithHashes.get(name).add(myVcsObjectsFactory.createHash(matcher.group(1)));
+ }
+ else {
+ Set hashes = new HashSet();
+ hashes.add(myVcsObjectsFactory.createHash(matcher.group(1)));
+ branchesWithHashes.put(name, hashes);
+ }
}
}
}
- return branches;
+ return branchesWithHashes;
}
public boolean isMergeInProgress() {
diff --git a/plugins/hg4idea/testSrc/hg4idea/test/repo/HgRealRepositoryReaderTest.java b/plugins/hg4idea/testSrc/hg4idea/test/repo/HgRealRepositoryReaderTest.java
index 306aade615ba..a1ec0c86a56f 100644
--- a/plugins/hg4idea/testSrc/hg4idea/test/repo/HgRealRepositoryReaderTest.java
+++ b/plugins/hg4idea/testSrc/hg4idea/test/repo/HgRealRepositoryReaderTest.java
@@ -19,7 +19,6 @@ import com.intellij.dvcs.repo.Repository;
import com.intellij.openapi.vcs.VcsTestUtil;
import hg4idea.test.HgPlatformTest;
import org.jetbrains.annotations.NotNull;
-import org.zmlx.hg4idea.HgVcs;
import org.zmlx.hg4idea.repo.HgRepositoryReader;
import org.zmlx.hg4idea.util.HgUtil;
@@ -59,7 +58,7 @@ public class HgRealRepositoryReaderTest extends HgPlatformTest {
}
public void testBranches() {
- VcsTestUtil.assertEqualCollections(HgUtil.getNamesWithoutHashes(myRepositoryReader.readBranches()),
+ VcsTestUtil.assertEqualCollections(myRepositoryReader.readBranches().keySet(),
Arrays.asList("default", "branchA", "branchB"));
}
diff --git a/plugins/hg4idea/testSrc/hg4idea/test/repo/HgRepositoryReaderTest.java b/plugins/hg4idea/testSrc/hg4idea/test/repo/HgRepositoryReaderTest.java
index bb94270fce05..dec100404c24 100644
--- a/plugins/hg4idea/testSrc/hg4idea/test/repo/HgRepositoryReaderTest.java
+++ b/plugins/hg4idea/testSrc/hg4idea/test/repo/HgRepositoryReaderTest.java
@@ -80,7 +80,7 @@ public class HgRepositoryReaderTest extends HgPlatformTest {
}
public void testBranches() {
- Collection branches = HgUtil.getNamesWithoutHashes(myRepositoryReader.readBranches());
+ Collection branches = myRepositoryReader.readBranches().keySet();
VcsTestUtil.assertEqualCollections(branches, myBranches);
}