Show unnamed branch heads without bookmarks and not current revision implemented.

*action for  showing unnamed heads added;
*branches storage structure changed to Map: key - heavy branch name, values - set of appropriate branch heads;
 *tests updated;
 *need to store current repository state,too.
This commit is contained in:
Nadya Zabrodina
2013-12-20 19:11:15 +04:00
parent 32ab1db769
commit 77792a3770
9 changed files with 124 additions and 38 deletions
@@ -38,11 +38,11 @@ public class HgNameWithHashInfo {
}
/**
* <p>Returns the hash on which this branch or bookmark or tag is reference to.</p>
* <p>Returns the hash on which this bookmark or tag is reference to.</p>
*/
@NotNull
public String getHash() {
return myHash.asString();
public Hash getHash() {
return myHash;
}
@NotNull
@@ -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<String> branchNames = HgUtil.getNamesWithoutHashes(myRepository.getBranches());
Collections.sort(branchNames);
for (String branch : branchNames) {
List<String> branchNamesList = new ArrayList<String>(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<Hash> myHeads = new HashSet<Hash>();
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<Hash> filterUnnamedHeads() {
Collection<Hash> branchWithHashes = myRepository.getBranches().get(myCurrentBranchName);
if (branchWithHashes == null) {
// repository is fresh or branch is fresh.
return Collections.emptySet();
}
else {
List<HgRevisionNumber> parents = new HgWorkingCopyRevisionsCommand(myProject).parents(myRepository.getRoot());
if (parents.size() == 1) {
Collection<Hash> bookmarkHashes = ContainerUtil.map(myRepository.getBookmarks(), new Function<HgNameWithHashInfo, Hash>() {
@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<AnAction> branchHeadActions = new ArrayList<AnAction>();
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.
@@ -103,18 +103,22 @@ public class HgLogProvider implements VcsLogProvider {
}
repository.update();
Collection<HgNameWithHashInfo> branches = repository.getBranches();
Map<String, Set<Hash>> branches = repository.getBranches();
Collection<HgNameWithHashInfo> bookmarks = repository.getBookmarks();
Collection<HgNameWithHashInfo> tags = repository.getTags();
Collection<HgNameWithHashInfo> localTags = repository.getLocalTags();
Collection<VcsRef> refs = new ArrayList<VcsRef>(branches.size() + bookmarks.size());
for (HgNameWithHashInfo branchInfo : branches) {
refs.add(myVcsObjectsFactory.createRef(myVcsObjectsFactory.createHash(branchInfo.getHash()), branchInfo.getName(), HgRefManager.BRANCH, root));
for (Map.Entry<String, Set<Hash>> 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;
@@ -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<HgNameWithHashInfo> myBranches = Collections.emptySet();
@NotNull private Map<String, Set<Hash>> myBranches = Collections.emptyMap();
@NotNull private Set<HgNameWithHashInfo> myBookmarks = Collections.emptySet();
@NotNull private Set<HgNameWithHashInfo> myTags = Collections.emptySet();
@NotNull private Set<HgNameWithHashInfo> myLocalTags = Collections.emptySet();
@@ -42,7 +40,7 @@ public class HgRepoInfo {
public HgRepoInfo(@NotNull String currentBranch,
@Nullable String currentRevision,
@NotNull Repository.State state,
@NotNull Collection<HgNameWithHashInfo> branches,
@NotNull Map<String,Set<Hash>> branches,
@NotNull Collection<HgNameWithHashInfo> bookmarks,
@Nullable String currentBookmark,
@NotNull Collection<HgNameWithHashInfo> tags,
@@ -50,7 +48,7 @@ public class HgRepoInfo {
myCurrentBranch = currentBranch;
myCurrentRevision = currentRevision;
myState = state;
myBranches = new LinkedHashSet<HgNameWithHashInfo>(branches);
myBranches = branches;
myBookmarks = new LinkedHashSet<HgNameWithHashInfo>(bookmarks);
myCurrentBookmark = currentBookmark;
myTags = new LinkedHashSet<HgNameWithHashInfo>(tags);
@@ -63,7 +61,7 @@ public class HgRepoInfo {
}
@NotNull
public Collection<HgNameWithHashInfo> getBranches() {
public Map<String, Set<Hash>> getBranches() {
return myBranches;
}
@@ -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<HgNameWithHashInfo> getBranches();
Map<String, Set<Hash>> getBranches();
@NotNull
Collection<HgNameWithHashInfo> getBookmarks();
@@ -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<HgNameWithHashInfo> getBranches() {
public Map<String, Set<Hash>> getBranches() {
return myInfo.getBranches();
}
@@ -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<HgNameWithHashInfo> readBranches() {
List<HgNameWithHashInfo> branches = new ArrayList<HgNameWithHashInfo>();
public Map<String, Set<Hash>> readBranches() {
Map<String, Set<Hash>> branchesWithHashes = new HashMap<String, Set<Hash>>();
// Set<String> branchNames = new HashSet<String>();
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<Hash> hashes = new HashSet<Hash>();
hashes.add(myVcsObjectsFactory.createHash(matcher.group(1)));
branchesWithHashes.put(name, hashes);
}
}
}
}
return branches;
return branchesWithHashes;
}
public boolean isMergeInProgress() {
@@ -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"));
}
@@ -80,7 +80,7 @@ public class HgRepositoryReaderTest extends HgPlatformTest {
}
public void testBranches() {
Collection<String> branches = HgUtil.getNamesWithoutHashes(myRepositoryReader.readBranches());
Collection<String> branches = myRepositoryReader.readBranches().keySet();
VcsTestUtil.assertEqualCollections(branches, myBranches);
}