[vcs]: add predefined favourite branches, add Branch manager

This commit is contained in:
Nadya Zabrodina
2017-01-11 16:45:33 +03:00
parent d3f6e0a13f
commit 05f626ff70
5 changed files with 123 additions and 43 deletions
+1
View File
@@ -147,6 +147,7 @@
<statistics.usagesCollector implementation="git4idea.GitStatisticsCollector" />
<projectService serviceImplementation="git4idea.repo.GitRepositoryManager"/>
<projectService serviceImplementation="git4idea.ui.branch.GitBranchManager"/>
<projectService
serviceInterface="git4idea.annotate.GitAnnotationProvider"
serviceImplementation="git4idea.annotate.GitAnnotationProvider"/>
@@ -41,8 +41,8 @@ public class GitRefManager implements VcsLogRefManager {
private static final List<VcsRefType> REF_TYPE_INDEX = Arrays.asList(HEAD, LOCAL_BRANCH, REMOTE_BRANCH, TAG, OTHER);
private static final String MASTER = "master";
private static final String ORIGIN_MASTER = "origin/master";
public static final String MASTER = "master";
public static final String ORIGIN_MASTER = "origin/master";
private static final Logger LOG = Logger.getInstance(GitRefManager.class);
private static final String REMOTE_TABLE_SEPARATOR = " & ";
private static final String SEPARATOR = "/";
@@ -0,0 +1,83 @@
/*
* Copyright 2000-2016 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 git4idea.ui.branch;
import com.intellij.dvcs.branch.BranchStorage;
import com.intellij.dvcs.branch.DvcsBranchInfo;
import git4idea.branch.GitBranchType;
import git4idea.config.GitVcsSettings;
import git4idea.repo.GitRepository;
import git4idea.repo.GitRepositoryManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import static git4idea.log.GitRefManager.MASTER;
import static git4idea.log.GitRefManager.ORIGIN_MASTER;
import static java.util.stream.Collectors.toList;
public class GitBranchManager {
@NotNull private final GitRepositoryManager myRepositoryManager;
@NotNull private final GitVcsSettings mySettings;
@NotNull public final BranchStorage myPredefinedFavouriteBranches = new BranchStorage();
public GitBranchManager(@NotNull GitRepositoryManager repositoryManager, @NotNull GitVcsSettings settings) {
myRepositoryManager = repositoryManager;
mySettings = settings;
for (GitBranchType type : GitBranchType.values()) {
myPredefinedFavouriteBranches.myBranches.put(type.toString(), constructDefaultBranchPredefinedList(type));
}
}
@NotNull
private List<DvcsBranchInfo> constructDefaultBranchPredefinedList(GitBranchType type) {
List<DvcsBranchInfo> branchInfos = myRepositoryManager.getRepositories().stream()
.map(repository -> new DvcsBranchInfo(repository.getRoot().getPath(), getDefaultBranchName(type)))
.collect(toList());
branchInfos.add(new DvcsBranchInfo("", getDefaultBranchName(type)));
return branchInfos;
}
@NotNull
private static String getDefaultBranchName(@NotNull GitBranchType type) {
return type == GitBranchType.GIT_LOCAL ? MASTER : ORIGIN_MASTER;
}
public boolean isFavourite(@NotNull GitBranchType branchType, @Nullable GitRepository repository, @NotNull String branchName) {
if (mySettings.isFavourite(branchType, repository, branchName)) return true;
//if (mySettings.isExcludedFromFavourites(branchType, repository, branchName)) return false;
return myPredefinedFavouriteBranches.contains(branchType.toString(), repository, branchName);
}
public void setFavourite(@NotNull GitBranchType branchType,
@Nullable GitRepository repository,
@NotNull String branchName,
boolean shouldBeFavourite) {
if (shouldBeFavourite) {
mySettings.addToFavourites(branchType, repository, branchName);
//mySettings.removeFromExcluded(branchType, repository, branchName);
}
else {
if (mySettings.isFavourite(branchType, repository, branchName)) {
mySettings.removeFromFavourites(branchType, repository, branchName);
}
else if (myPredefinedFavouriteBranches.contains(branchType.toString(), repository, branchName)) {
//mySettings.excludedFromFavourites()
}
}
}
}
@@ -40,6 +40,7 @@ import static com.intellij.dvcs.branch.DvcsBranchPopup.MyMoreIndex.*;
import static com.intellij.dvcs.ui.BranchActionGroupPopup.addMoreActionIfNeeded;
import static com.intellij.dvcs.ui.BranchActionUtil.FAVOURITE_BRANCH_COMPARATOR;
import static com.intellij.dvcs.ui.BranchActionUtil.getNumOfFavourites;
import static com.intellij.util.containers.ContainerUtil.map;
import static java.util.stream.Collectors.toList;
/**
@@ -124,9 +125,11 @@ class GitBranchPopup extends DvcsBranchPopup<GitRepository> {
popupGroup.addAll(localBranchPresentationList);
popupGroup.addSeparator("Common Remote Branches");
List<BranchActionGroup> remoteBranchActions =
((GitMultiRootBranchConfig)myMultiRootBranchConfig).getRemoteBranches().stream()
.map(r -> new GitBranchPopupActions.RemoteBranchActions(myProject, allRepositories, r, myCurrentRepository)).collect(toList());
List<BranchActionGroup> remoteBranchActions = map(((GitMultiRootBranchConfig)myMultiRootBranchConfig).getRemoteBranches(),
remoteBranch -> new GitBranchPopupActions.RemoteBranchActions(myProject,
allRepositories,
remoteBranch,
myCurrentRepository));
numOfFavourites = getNumOfFavourites(remoteBranchActions);
List<AnAction> remoteBranchPresentationList =
remoteBranchActions.stream().sorted(FAVOURITE_BRANCH_COMPARATOR).collect(toList());
@@ -29,7 +29,6 @@ import com.intellij.openapi.ui.Messages;
import com.intellij.util.containers.ContainerUtil;
import git4idea.branch.GitBranchUtil;
import git4idea.branch.GitBrancher;
import git4idea.config.GitVcsSettings;
import git4idea.repo.GitRepository;
import git4idea.validators.GitNewBranchNameValidator;
import org.jetbrains.annotations.NotNull;
@@ -37,7 +36,6 @@ import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import static com.intellij.dvcs.branch.DvcsBranchPopup.MyMoreIndex.MAX_BRANCH_NUM;
import static com.intellij.dvcs.ui.BranchActionGroupPopup.addMoreActionIfNeeded;
@@ -46,6 +44,7 @@ import static com.intellij.dvcs.ui.BranchActionUtil.getNumOfFavourites;
import static git4idea.GitStatisticsCollectorKt.reportUsage;
import static git4idea.branch.GitBranchType.GIT_LOCAL;
import static git4idea.branch.GitBranchType.GIT_REMOTE;
import static java.util.stream.Collectors.toList;
class GitBranchPopupActions {
@@ -74,22 +73,25 @@ class GitBranchPopupActions {
popupGroup.addSeparator("Local Branches" + repoInfo);
List<BranchActionGroup> localBranchActions =
myRepository.getBranches().getLocalBranches().stream().sorted().filter(l -> !l.equals(myRepository.getCurrentBranch()))
.map(l -> new LocalBranchActions(myProject, repositoryList, l.getName(), myRepository)).collect(
Collectors.toList());
myRepository.getBranches().getLocalBranches().stream()
.sorted()
.filter(branch -> !branch.equals(myRepository.getCurrentBranch()))
.map(branch -> new LocalBranchActions(myProject, repositoryList, branch.getName(), myRepository))
.collect(toList());
int numOfFavourites = getNumOfFavourites(localBranchActions);
List<AnAction> localBranchPresentationList =
localBranchActions.stream().sorted(FAVOURITE_BRANCH_COMPARATOR).collect(Collectors.toList());
List<AnAction> localBranchPresentationList = localBranchActions.stream().sorted(FAVOURITE_BRANCH_COMPARATOR).collect(toList());
// if there are only a few local favourites -> show several non-favourite; for remotes it's better to show only favourites;
addMoreActionIfNeeded(localBranchPresentationList, numOfFavourites > MAX_BRANCH_NUM ? numOfFavourites : MAX_BRANCH_NUM);
popupGroup.addAll(localBranchPresentationList);
popupGroup.addSeparator("Remote Branches" + repoInfo);
List<BranchActionGroup> remoteBranchActions = myRepository.getBranches().getRemoteBranches().stream().sorted()
.map(r -> new RemoteBranchActions(myProject, repositoryList, r.getName(), myRepository))
.collect(Collectors.toList());
List<BranchActionGroup> remoteBranchActions =
myRepository.getBranches().getRemoteBranches().stream()
.sorted()
.map(remoteBranch -> new RemoteBranchActions(myProject, repositoryList, remoteBranch.getName(), myRepository))
.collect(toList());
numOfFavourites = getNumOfFavourites(remoteBranchActions);
List<AnAction> remoteBranchPresentationList =
remoteBranchActions.stream().sorted(FAVOURITE_BRANCH_COMPARATOR).collect(Collectors.toList());
List<AnAction> remoteBranchPresentationList = remoteBranchActions.stream().sorted(FAVOURITE_BRANCH_COMPARATOR).collect(toList());
addMoreActionIfNeeded(remoteBranchPresentationList, numOfFavourites > MAX_BRANCH_NUM ? numOfFavourites : MAX_BRANCH_NUM);
popupGroup.addAll(remoteBranchPresentationList);
return popupGroup;
@@ -125,7 +127,8 @@ class GitBranchPopupActions {
myRepositories = repositories;
}
@Override public void actionPerformed(AnActionEvent e) {
@Override
public void actionPerformed(AnActionEvent e) {
// TODO autocomplete branches, tags.
// on type check ref validity, on OK check ref existence.
String reference = Messages
@@ -153,10 +156,10 @@ class GitBranchPopupActions {
static class LocalBranchActions extends BranchActionGroup implements PopupElementWithAdditionalInfo {
private final Project myProject;
private final GitVcsSettings myGitVcsSettings;
private final List<GitRepository> myRepositories;
private final String myBranchName;
@NotNull private final GitRepository mySelectedRepository;
private final GitBranchManager myGitBranchManager;
LocalBranchActions(@NotNull Project project, @NotNull List<GitRepository> repositories, @NotNull String branchName,
@NotNull GitRepository selectedRepository) {
@@ -164,9 +167,9 @@ class GitBranchPopupActions {
myRepositories = repositories;
myBranchName = branchName;
mySelectedRepository = selectedRepository;
myGitVcsSettings = GitVcsSettings.getInstance(project);
myGitBranchManager = ServiceManager.getService(project, GitBranchManager.class);
getTemplatePresentation().setText(calcBranchText(), false); // no mnemonics
setFavourite(myGitVcsSettings.isFavourite(GIT_LOCAL, repositories.size() > 1 ? null : mySelectedRepository, myBranchName));
setFavourite(myGitBranchManager.isFavourite(GIT_LOCAL, repositories.size() > 1 ? null : mySelectedRepository, myBranchName));
}
@NotNull
@@ -187,7 +190,7 @@ class GitBranchPopupActions {
@NotNull
@Override
public AnAction[] getChildren(@Nullable AnActionEvent e) {
return new AnAction[] {
return new AnAction[]{
new CheckoutAction(myProject, myRepositories, myBranchName),
new CheckoutAsNewBranch(myProject, myRepositories, myBranchName),
new CompareAction(myProject, myRepositories, myBranchName, mySelectedRepository),
@@ -202,18 +205,13 @@ class GitBranchPopupActions {
@Override
@Nullable
public String getInfoText() {
return new GitMultiRootBranchConfig(myRepositories).getTrackedBranch(myBranchName);
return new GitMultiRootBranchConfig(myRepositories).getTrackedBranch(myBranchName);
}
@Override
public void toggle() {
super.toggle();
if (isFavourite()) {
myGitVcsSettings.addToFavourites(GIT_LOCAL, myRepositories.size() > 1 ? null : mySelectedRepository, myBranchName);
}
else {
myGitVcsSettings.removeFromFavourites(GIT_LOCAL, myRepositories.size() > 1 ? null : mySelectedRepository, myBranchName);
}
myGitBranchManager.setFavourite(GIT_LOCAL, myRepositories.size() > 1 ? null : mySelectedRepository, myBranchName, isFavourite());
}
static class CheckoutAction extends DumbAwareAction {
@@ -313,38 +311,33 @@ class GitBranchPopupActions {
static class RemoteBranchActions extends BranchActionGroup {
private final Project myProject;
private final GitVcsSettings myGitVcsSettings;
private final List<GitRepository> myRepositories;
private final String myBranchName;
@NotNull private final GitRepository mySelectedRepository;
@NotNull private final GitBranchManager myGitBranchManager;
RemoteBranchActions(@NotNull Project project, @NotNull List<GitRepository> repositories, @NotNull String branchName,
@NotNull GitRepository selectedRepository) {
myProject = project;
myRepositories = repositories;
myBranchName = branchName;
mySelectedRepository = selectedRepository;
myGitVcsSettings = GitVcsSettings.getInstance(project);
myGitBranchManager = ServiceManager.getService(project, GitBranchManager.class);
getTemplatePresentation().setText(myBranchName, false); // no mnemonics
setFavourite(myGitVcsSettings.isFavourite(GIT_REMOTE, repositories.size() > 1 ? null : mySelectedRepository, myBranchName));
setFavourite(myGitBranchManager.isFavourite(GIT_REMOTE, repositories.size() > 1 ? null : mySelectedRepository, myBranchName));
}
@Override
public void toggle() {
super.toggle();
if (isFavourite()) {
myGitVcsSettings.addToFavourites(GIT_REMOTE, myRepositories.size() > 1 ? null : mySelectedRepository, myBranchName);
}
else {
myGitVcsSettings.removeFromFavourites(GIT_REMOTE, myRepositories.size() > 1 ? null : mySelectedRepository, myBranchName);
}
myGitBranchManager.setFavourite(GIT_REMOTE, myRepositories.size() > 1 ? null : mySelectedRepository, myBranchName, isFavourite());
}
@NotNull
@Override
public AnAction[] getChildren(@Nullable AnActionEvent e) {
return new AnAction[] {
return new AnAction[]{
new CheckoutRemoteBranchAction(myProject, myRepositories, myBranchName),
new CompareAction(myProject, myRepositories, myBranchName, mySelectedRepository),
new RebaseAction(myProject, myRepositories, myBranchName),
@@ -369,7 +362,7 @@ class GitBranchPopupActions {
@Override
public void actionPerformed(AnActionEvent e) {
final String name = Messages.showInputDialog(myProject, "New branch name:", "Checkout Remote Branch", null,
guessBranchName(), GitNewBranchNameValidator.newInstance(myRepositories));
guessBranchName(), GitNewBranchNameValidator.newInstance(myRepositories));
if (name != null) {
GitBrancher brancher = ServiceManager.getService(myProject, GitBrancher.class);
brancher.checkoutNewBranchStartingFrom(name, myRemoteBranchName, myRepositories, null);
@@ -381,7 +374,7 @@ class GitBranchPopupActions {
// TODO: check if we already have a branch with that name; check if that branch tracks this remote branch. Show different messages
int slashPosition = myRemoteBranchName.indexOf("/");
// if no slash is found (for example, in the case of git-svn remote branches), propose the whole name.
return myRemoteBranchName.substring(slashPosition+1);
return myRemoteBranchName.substring(slashPosition + 1);
}
}
@@ -405,7 +398,7 @@ class GitBranchPopupActions {
}
}
}
private static class CompareAction extends DumbAwareAction {
private final Project myProject;