mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[vcs]: implement favourite-branches serialization
* add git realization
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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 com.intellij.dvcs.branch;
|
||||
|
||||
import com.intellij.dvcs.repo.Repository;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.xmlb.annotations.MapAnnotation;
|
||||
import com.intellij.util.xmlb.annotations.Property;
|
||||
import com.intellij.util.xmlb.annotations.Tag;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.intellij.dvcs.branch.DvcsBranchUtil.find;
|
||||
import static com.intellij.util.containers.ContainerUtil.newArrayList;
|
||||
|
||||
@Tag("branch-storage")
|
||||
public class BranchStorage {
|
||||
|
||||
@Property(surroundWithTag = false)
|
||||
@MapAnnotation(keyAttributeName = "type")
|
||||
@NotNull public Map<String, List<DvcsBranchInfo>> myBranches = ContainerUtil.newHashMap();
|
||||
|
||||
public BranchStorage() {
|
||||
}
|
||||
|
||||
public boolean contains(@NotNull String typeName, @Nullable Repository repository, @NotNull String branchName) {
|
||||
List<DvcsBranchInfo> branches = myBranches.get(typeName);
|
||||
return branches != null && find(branches, repository, branchName) != null;
|
||||
}
|
||||
|
||||
public void add(@NotNull String typeName, @Nullable Repository repository,
|
||||
@NotNull String branchName) {
|
||||
if (contains(typeName, repository, branchName)) return;
|
||||
List<DvcsBranchInfo> branchInfos = myBranches.computeIfAbsent(typeName, name -> newArrayList());
|
||||
branchInfos.add(new DvcsBranchInfo(DvcsBranchUtil.getPathFor(repository), branchName));
|
||||
}
|
||||
|
||||
public void remove(@NotNull String typeName, @Nullable Repository repository,
|
||||
@NotNull String branchName) {
|
||||
|
||||
List<DvcsBranchInfo> branches = myBranches.get(typeName);
|
||||
DvcsBranchInfo toDelete = find(branches, repository, branchName);
|
||||
if (toDelete != null) {
|
||||
branches.remove(toDelete);
|
||||
if (branches.isEmpty()) {
|
||||
myBranches.remove(typeName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.intellij.dvcs.branch;
|
||||
|
||||
import com.intellij.util.xmlb.annotations.Attribute;
|
||||
import com.intellij.util.xmlb.annotations.Tag;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@Tag("branch-info")
|
||||
public class DvcsBranchInfo {
|
||||
@Attribute(value = "repo") public final String repoPath;
|
||||
@Attribute(value = "source") public final String sourceName;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public DvcsBranchInfo() {
|
||||
this("", "");
|
||||
}
|
||||
|
||||
public DvcsBranchInfo(String repositoryPath, String source) {
|
||||
repoPath = repositoryPath;
|
||||
sourceName = source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
DvcsBranchInfo info = (DvcsBranchInfo)o;
|
||||
|
||||
if (repoPath != null ? !repoPath.equals(info.repoPath) : info.repoPath != null) return false;
|
||||
if (sourceName != null ? !sourceName.equals(info.sourceName) : info.sourceName != null) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(repoPath, sourceName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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 com.intellij.dvcs.branch;
|
||||
|
||||
import com.intellij.dvcs.repo.Repository;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class DvcsBranchUtil {
|
||||
|
||||
|
||||
@Nullable
|
||||
public static <T extends DvcsBranchInfo> T find(@Nullable final Collection<T> branches,
|
||||
@Nullable Repository repository,
|
||||
@NotNull String sourceBranch) {
|
||||
if (branches == null) return null;
|
||||
return ContainerUtil.find(branches, targetInfo -> repoAndSourceAreEqual(repository, sourceBranch, targetInfo));
|
||||
}
|
||||
|
||||
private static boolean repoAndSourceAreEqual(@Nullable Repository repository,
|
||||
@NotNull String sourceBranch,
|
||||
@NotNull DvcsBranchInfo targetInfo) {
|
||||
return getPathFor(repository).equals(targetInfo.repoPath) && StringUtil.equals(targetInfo.sourceName, sourceBranch);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getPathFor(@Nullable Repository repository) {
|
||||
return repository == null ? "" : repository.getRoot().getPath();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* 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.branch;
|
||||
|
||||
|
||||
public enum GitBranchType {
|
||||
GIT_LOCAL, GIT_REMOTE
|
||||
}
|
||||
@@ -15,7 +15,10 @@
|
||||
*/
|
||||
package git4idea.config;
|
||||
|
||||
import com.intellij.dvcs.branch.BranchStorage;
|
||||
import com.intellij.dvcs.branch.DvcsBranchInfo;
|
||||
import com.intellij.dvcs.branch.DvcsSyncSettings;
|
||||
import com.intellij.dvcs.repo.Repository;
|
||||
import com.intellij.lifecycle.PeriodicalTasksCloser;
|
||||
import com.intellij.openapi.components.PersistentStateComponent;
|
||||
import com.intellij.openapi.components.State;
|
||||
@@ -30,16 +33,18 @@ import com.intellij.util.xmlb.annotations.Attribute;
|
||||
import com.intellij.util.xmlb.annotations.Tag;
|
||||
import git4idea.GitRemoteBranch;
|
||||
import git4idea.GitUtil;
|
||||
import git4idea.branch.GitBranchType;
|
||||
import git4idea.push.GitPushTagMode;
|
||||
import git4idea.repo.GitRemote;
|
||||
import git4idea.repo.GitRepository;
|
||||
import git4idea.reset.GitResetMode;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static com.intellij.dvcs.branch.DvcsBranchUtil.find;
|
||||
|
||||
/**
|
||||
* Git VCS settings
|
||||
*/
|
||||
@@ -83,6 +88,9 @@ public class GitVcsSettings implements PersistentStateComponent<GitVcsSettings.S
|
||||
@AbstractCollection(surroundWithTag = false)
|
||||
@Tag("push-targets")
|
||||
public List<PushTargetInfo> PUSH_TARGETS = ContainerUtil.newArrayList();
|
||||
|
||||
@Tag("favourite-branches")
|
||||
public BranchStorage FAVOURITE_BRANCHES = new BranchStorage();
|
||||
}
|
||||
|
||||
public GitVcsSettings(GitVcsApplicationSettings appSettings) {
|
||||
@@ -265,50 +273,37 @@ public class GitVcsSettings implements PersistentStateComponent<GitVcsSettings.S
|
||||
|
||||
@Nullable
|
||||
public GitRemoteBranch getPushTarget(@NotNull GitRepository repository, @NotNull String sourceBranch) {
|
||||
Iterator<PushTargetInfo> iterator = myState.PUSH_TARGETS.iterator();
|
||||
PushTargetInfo targetInfo = find(iterator, repository, sourceBranch);
|
||||
if (targetInfo == null) {
|
||||
return null;
|
||||
}
|
||||
PushTargetInfo targetInfo = find(myState.PUSH_TARGETS, repository, sourceBranch);
|
||||
if (targetInfo == null) return null;
|
||||
GitRemote remote = GitUtil.findRemoteByName(repository, targetInfo.targetRemoteName);
|
||||
if (remote == null) {
|
||||
return null;
|
||||
}
|
||||
if (remote == null) return null;
|
||||
return GitUtil.findOrCreateRemoteBranch(repository, remote, targetInfo.targetBranchName);
|
||||
}
|
||||
|
||||
public void setPushTarget(@NotNull GitRepository repository, @NotNull String sourceBranch,
|
||||
@NotNull String targetRemote, @NotNull String targetBranch) {
|
||||
String repositoryPath = repository.getRoot().getPath();
|
||||
List<PushTargetInfo> targets = new ArrayList<>(myState.PUSH_TARGETS);
|
||||
Iterator<PushTargetInfo> iterator = targets.iterator();
|
||||
PushTargetInfo existingInfo = find(iterator, repository, sourceBranch);
|
||||
PushTargetInfo existingInfo = find(myState.PUSH_TARGETS, repository, sourceBranch);
|
||||
if (existingInfo != null) {
|
||||
iterator.remove();
|
||||
myState.PUSH_TARGETS.remove(existingInfo);
|
||||
}
|
||||
PushTargetInfo newInfo = new PushTargetInfo(repositoryPath, sourceBranch, targetRemote, targetBranch);
|
||||
targets.add(newInfo);
|
||||
myState.PUSH_TARGETS = targets;
|
||||
myState.PUSH_TARGETS.add(new PushTargetInfo(repositoryPath, sourceBranch, targetRemote, targetBranch));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Contract(pure = false)
|
||||
private static PushTargetInfo find(@NotNull Iterator<PushTargetInfo> iterator,
|
||||
@NotNull GitRepository repository,
|
||||
@NotNull String sourceBranch) {
|
||||
while (iterator.hasNext()) {
|
||||
PushTargetInfo targetInfo = iterator.next();
|
||||
if (targetInfo.repoPath.equals(repository.getRoot().getPath()) && targetInfo.sourceName.equals(sourceBranch)) {
|
||||
return targetInfo;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
public void addToFavourites(@NotNull GitBranchType type, @Nullable GitRepository repository, @NotNull String branchName) {
|
||||
myState.FAVOURITE_BRANCHES.add(type.toString(), repository, branchName);
|
||||
}
|
||||
|
||||
public void removeFromFavourites(@NotNull GitBranchType type, @Nullable GitRepository repository, @NotNull String branchName) {
|
||||
myState.FAVOURITE_BRANCHES.remove(type.toString(), repository, branchName);
|
||||
}
|
||||
|
||||
public boolean isFavourite(@NotNull GitBranchType type, @Nullable Repository repository, @NotNull String branchName) {
|
||||
return myState.FAVOURITE_BRANCHES.contains(type.toString(), repository, branchName);
|
||||
}
|
||||
|
||||
@Tag("push-target-info")
|
||||
private static class PushTargetInfo {
|
||||
@Attribute(value = "repo") public String repoPath;
|
||||
@Attribute(value = "source") public String sourceName;
|
||||
private static class PushTargetInfo extends DvcsBranchInfo {
|
||||
@Attribute(value = "target-remote") public String targetRemoteName;
|
||||
@Attribute(value = "target-branch") public String targetBranchName;
|
||||
|
||||
@@ -318,10 +313,28 @@ public class GitVcsSettings implements PersistentStateComponent<GitVcsSettings.S
|
||||
}
|
||||
|
||||
PushTargetInfo(@NotNull String repositoryPath, @NotNull String source, @NotNull String targetRemote, @NotNull String targetBranch) {
|
||||
repoPath = repositoryPath;
|
||||
sourceName = source;
|
||||
super(repositoryPath, source);
|
||||
targetRemoteName = targetRemote;
|
||||
targetBranchName = targetBranch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
if (!super.equals(o)) return false;
|
||||
|
||||
PushTargetInfo info = (PushTargetInfo)o;
|
||||
|
||||
if (targetRemoteName != null ? !targetRemoteName.equals(info.targetRemoteName) : info.targetRemoteName != null) return false;
|
||||
if (targetBranchName != null ? !targetBranchName.equals(info.targetBranchName) : info.targetBranchName != null) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(super.hashCode(), targetRemoteName,targetBranchName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ 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;
|
||||
@@ -41,6 +42,8 @@ import java.util.stream.Collectors;
|
||||
import static com.intellij.dvcs.branch.DvcsBranchPopup.MyMoreIndex.MAX_BRANCH_NUM;
|
||||
import static com.intellij.dvcs.ui.BranchActionGroupPopup.addMoreActionIfNeeded;
|
||||
import static git4idea.GitStatisticsCollectorKt.reportUsage;
|
||||
import static git4idea.branch.GitBranchType.GIT_LOCAL;
|
||||
import static git4idea.branch.GitBranchType.GIT_REMOTE;
|
||||
|
||||
class GitBranchPopupActions {
|
||||
|
||||
@@ -142,6 +145,7 @@ 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;
|
||||
@@ -152,7 +156,9 @@ class GitBranchPopupActions {
|
||||
myRepositories = repositories;
|
||||
myBranchName = branchName;
|
||||
mySelectedRepository = selectedRepository;
|
||||
myGitVcsSettings = GitVcsSettings.getInstance(project);
|
||||
getTemplatePresentation().setText(calcBranchText(), false); // no mnemonics
|
||||
setFavourite(myGitVcsSettings.isFavourite(GIT_LOCAL, repositories.size() > 1 ? null : mySelectedRepository, myBranchName));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -191,6 +197,17 @@ class GitBranchPopupActions {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
static class CheckoutAction extends DumbAwareAction {
|
||||
private final Project myProject;
|
||||
private final List<GitRepository> myRepositories;
|
||||
@@ -288,17 +305,32 @@ 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;
|
||||
|
||||
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);
|
||||
getTemplatePresentation().setText(myBranchName, false); // no mnemonics
|
||||
setFavourite(myGitVcsSettings.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);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
Reference in New Issue
Block a user