From 05f626ff70e70258ca696c807459de53521b3237 Mon Sep 17 00:00:00 2001 From: Nadya Zabrodina Date: Wed, 21 Dec 2016 19:33:41 +0300 Subject: [PATCH] [vcs]: add predefined favourite branches, add Branch manager --- plugins/git4idea/src/META-INF/plugin.xml | 1 + .../src/git4idea/log/GitRefManager.java | 4 +- .../git4idea/ui/branch/GitBranchManager.java | 83 +++++++++++++++++++ .../git4idea/ui/branch/GitBranchPopup.java | 9 +- .../ui/branch/GitBranchPopupActions.java | 69 +++++++-------- 5 files changed, 123 insertions(+), 43 deletions(-) create mode 100644 plugins/git4idea/src/git4idea/ui/branch/GitBranchManager.java diff --git a/plugins/git4idea/src/META-INF/plugin.xml b/plugins/git4idea/src/META-INF/plugin.xml index dab1253adec8..263f9ab60439 100644 --- a/plugins/git4idea/src/META-INF/plugin.xml +++ b/plugins/git4idea/src/META-INF/plugin.xml @@ -147,6 +147,7 @@ + diff --git a/plugins/git4idea/src/git4idea/log/GitRefManager.java b/plugins/git4idea/src/git4idea/log/GitRefManager.java index 53b130d9551e..ac0eb0d2dd27 100644 --- a/plugins/git4idea/src/git4idea/log/GitRefManager.java +++ b/plugins/git4idea/src/git4idea/log/GitRefManager.java @@ -41,8 +41,8 @@ public class GitRefManager implements VcsLogRefManager { private static final List 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 = "/"; diff --git a/plugins/git4idea/src/git4idea/ui/branch/GitBranchManager.java b/plugins/git4idea/src/git4idea/ui/branch/GitBranchManager.java new file mode 100644 index 000000000000..381ba94d138f --- /dev/null +++ b/plugins/git4idea/src/git4idea/ui/branch/GitBranchManager.java @@ -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 constructDefaultBranchPredefinedList(GitBranchType type) { + List 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() + } + } + } +} diff --git a/plugins/git4idea/src/git4idea/ui/branch/GitBranchPopup.java b/plugins/git4idea/src/git4idea/ui/branch/GitBranchPopup.java index e7a1574cbd7a..5fd879c29fd2 100644 --- a/plugins/git4idea/src/git4idea/ui/branch/GitBranchPopup.java +++ b/plugins/git4idea/src/git4idea/ui/branch/GitBranchPopup.java @@ -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 { popupGroup.addAll(localBranchPresentationList); popupGroup.addSeparator("Common Remote Branches"); - List remoteBranchActions = - ((GitMultiRootBranchConfig)myMultiRootBranchConfig).getRemoteBranches().stream() - .map(r -> new GitBranchPopupActions.RemoteBranchActions(myProject, allRepositories, r, myCurrentRepository)).collect(toList()); + List remoteBranchActions = map(((GitMultiRootBranchConfig)myMultiRootBranchConfig).getRemoteBranches(), + remoteBranch -> new GitBranchPopupActions.RemoteBranchActions(myProject, + allRepositories, + remoteBranch, + myCurrentRepository)); numOfFavourites = getNumOfFavourites(remoteBranchActions); List remoteBranchPresentationList = remoteBranchActions.stream().sorted(FAVOURITE_BRANCH_COMPARATOR).collect(toList()); diff --git a/plugins/git4idea/src/git4idea/ui/branch/GitBranchPopupActions.java b/plugins/git4idea/src/git4idea/ui/branch/GitBranchPopupActions.java index f07151e30103..ec038e36cc8f 100644 --- a/plugins/git4idea/src/git4idea/ui/branch/GitBranchPopupActions.java +++ b/plugins/git4idea/src/git4idea/ui/branch/GitBranchPopupActions.java @@ -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 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 localBranchPresentationList = - localBranchActions.stream().sorted(FAVOURITE_BRANCH_COMPARATOR).collect(Collectors.toList()); + List 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 remoteBranchActions = myRepository.getBranches().getRemoteBranches().stream().sorted() - .map(r -> new RemoteBranchActions(myProject, repositoryList, r.getName(), myRepository)) - .collect(Collectors.toList()); + List remoteBranchActions = + myRepository.getBranches().getRemoteBranches().stream() + .sorted() + .map(remoteBranch -> new RemoteBranchActions(myProject, repositoryList, remoteBranch.getName(), myRepository)) + .collect(toList()); numOfFavourites = getNumOfFavourites(remoteBranchActions); - List remoteBranchPresentationList = - remoteBranchActions.stream().sorted(FAVOURITE_BRANCH_COMPARATOR).collect(Collectors.toList()); + List 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 myRepositories; private final String myBranchName; @NotNull private final GitRepository mySelectedRepository; + private final GitBranchManager myGitBranchManager; LocalBranchActions(@NotNull Project project, @NotNull List 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 myRepositories; private final String myBranchName; @NotNull private final GitRepository mySelectedRepository; + @NotNull private final GitBranchManager myGitBranchManager; RemoteBranchActions(@NotNull Project project, @NotNull List 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;