mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[vcs-log] structure filter better understand nature of vcs roots and interacts with branches filter about them
This commit is contained in:
@@ -34,4 +34,6 @@ public interface VcsLogStructureFilter extends VcsLogDetailsFilter {
|
||||
@NotNull
|
||||
Collection<VirtualFile> getFiles(@NotNull VirtualFile root);
|
||||
|
||||
Collection<VirtualFile> getRoots();
|
||||
|
||||
}
|
||||
|
||||
+55
-41
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 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.
|
||||
@@ -23,61 +23,47 @@ import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import com.intellij.vcs.log.VcsCommitMetadata;
|
||||
import com.intellij.vcs.log.VcsFullCommitDetails;
|
||||
import com.intellij.vcs.log.VcsLogDetailsFilter;
|
||||
import com.intellij.vcs.log.VcsLogStructureFilter;
|
||||
import com.intellij.vcs.log.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class VcsLogStructureFilterImpl implements VcsLogDetailsFilter, VcsLogStructureFilter {
|
||||
@NotNull private final Set<VirtualFile> myRoots;
|
||||
@NotNull private final MultiMap<VirtualFile, VirtualFile> myRootToFiles;
|
||||
|
||||
@NotNull private final Collection<VirtualFile> myFiles;
|
||||
@NotNull private final MultiMap<VirtualFile, VirtualFile> myFilesByRoots;
|
||||
|
||||
public VcsLogStructureFilterImpl(@NotNull Collection<VirtualFile> files, @NotNull Collection<VirtualFile> roots) {
|
||||
myFiles = files;
|
||||
myFilesByRoots = groupFilesByVcsRoots(files, roots);
|
||||
public VcsLogStructureFilterImpl(@NotNull Set<VirtualFile> roots,
|
||||
@NotNull MultiMap<VirtualFile, VirtualFile> rootToFiles) {
|
||||
myRoots = roots;
|
||||
myRootToFiles = rootToFiles;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static MultiMap<VirtualFile, VirtualFile> groupFilesByVcsRoots(@NotNull Collection<VirtualFile> files,
|
||||
@NotNull Collection<VirtualFile> roots) {
|
||||
MultiMap<VirtualFile, VirtualFile> grouped = MultiMap.create();
|
||||
for (VirtualFile file : files) {
|
||||
VirtualFile root = findBestRoot(file, roots);
|
||||
if (root != null) {
|
||||
grouped.putValue(root, file);
|
||||
}
|
||||
}
|
||||
return grouped;
|
||||
@Override
|
||||
public Collection<VirtualFile> getFiles(@NotNull VirtualFile root) {
|
||||
return myRootToFiles.get(root);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static VirtualFile findBestRoot(@NotNull VirtualFile file, @NotNull Collection<VirtualFile> roots) {
|
||||
VirtualFile candidate = null;
|
||||
for (VirtualFile root : roots) {
|
||||
if (VfsUtilCore.isAncestor(root, file, false)) {
|
||||
if (candidate == null || VfsUtilCore.isAncestor(candidate, root, true)) {
|
||||
candidate = root;
|
||||
}
|
||||
}
|
||||
}
|
||||
return candidate;
|
||||
@Override
|
||||
public Collection<VirtualFile> getRoots() {
|
||||
return ContainerUtil.union(myRoots, myRootToFiles.keySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(@NotNull VcsCommitMetadata details) {
|
||||
if (myRoots.contains(details.getRoot())) return true;
|
||||
|
||||
if ((details instanceof VcsFullCommitDetails)) {
|
||||
for (Change change : ((VcsFullCommitDetails)details).getChanges()) {
|
||||
ContentRevision before = change.getBeforeRevision();
|
||||
if (before != null && matches(before.getFile().getPath())) {
|
||||
if (before != null && matches(before.getFile().getPath(), myRootToFiles.get(details.getRoot()))) {
|
||||
return true;
|
||||
}
|
||||
ContentRevision after = change.getAfterRevision();
|
||||
if (after != null && matches(after.getFile().getPath())) {
|
||||
if (after != null && matches(after.getFile().getPath(), myRootToFiles.get(details.getRoot()))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -88,8 +74,8 @@ public class VcsLogStructureFilterImpl implements VcsLogDetailsFilter, VcsLogStr
|
||||
}
|
||||
}
|
||||
|
||||
private boolean matches(@NotNull final String path) {
|
||||
return ContainerUtil.find(myFiles, new Condition<VirtualFile>() {
|
||||
private boolean matches(@NotNull final String path, @NotNull Collection<VirtualFile> files) {
|
||||
return ContainerUtil.find(files, new Condition<VirtualFile>() {
|
||||
@Override
|
||||
public boolean value(VirtualFile file) {
|
||||
return FileUtil.isAncestor(file.getPath(), path, false);
|
||||
@@ -97,10 +83,38 @@ public class VcsLogStructureFilterImpl implements VcsLogDetailsFilter, VcsLogStr
|
||||
}) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Collection<VirtualFile> getFiles(@NotNull VirtualFile root) {
|
||||
return myFilesByRoots.get(root);
|
||||
}
|
||||
public static VcsLogStructureFilterImpl build(@NotNull Collection<VirtualFile> files,
|
||||
@NotNull VcsLogDataPack dataPack) {
|
||||
Set<VirtualFile> roots = dataPack.getLogProviders().keySet();
|
||||
|
||||
Set<VirtualFile> selectedRoots = new HashSet<VirtualFile>();
|
||||
MultiMap<VirtualFile, VirtualFile> selectedFiles = new MultiMap<VirtualFile, VirtualFile>();
|
||||
|
||||
for (VirtualFile file : files) {
|
||||
if (roots.contains(file)) {
|
||||
// no need in details filter
|
||||
selectedRoots.add(file);
|
||||
}
|
||||
else {
|
||||
VirtualFile candidateAncestorRoot = null;
|
||||
for (VirtualFile root : roots) {
|
||||
if (VfsUtilCore.isAncestor(root, file, false)) {
|
||||
if (candidateAncestorRoot == null || VfsUtilCore.isAncestor(candidateAncestorRoot, root, false)) {
|
||||
candidateAncestorRoot = root;
|
||||
}
|
||||
}
|
||||
else if (VfsUtilCore.isAncestor(file, root, false)) {
|
||||
selectedRoots.add(root);
|
||||
}
|
||||
}
|
||||
|
||||
if (candidateAncestorRoot != null) {
|
||||
selectedFiles.putValue(candidateAncestorRoot, file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new VcsLogStructureFilterImpl(selectedRoots, selectedFiles);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,7 +207,7 @@ class VisiblePackBuilder {
|
||||
for (Map.Entry<VirtualFile, VcsLogProvider> entry : providers.entrySet()) {
|
||||
VirtualFile root = entry.getKey();
|
||||
|
||||
if (filterCollection.getStructureFilter() != null && filterCollection.getStructureFilter().getFiles(root).isEmpty()
|
||||
if (filterCollection.getStructureFilter() != null && !filterCollection.getStructureFilter().getRoots().contains(root)
|
||||
|| filterCollection.getUserFilter() != null && filterCollection.getUserFilter().getUserNames(root).isEmpty()) {
|
||||
// there is a structure or user filter, but it doesn't match this root
|
||||
continue;
|
||||
|
||||
+7
-4
@@ -68,7 +68,11 @@ class StructureFilterPopupComponent extends FilterPopupComponent<VcsLogStructure
|
||||
private static Collection<VirtualFile> getAllFiles(@NotNull VcsLogDataPack dataPack, @NotNull VcsLogStructureFilter filter) {
|
||||
Collection<VirtualFile> result = ContainerUtil.newArrayList();
|
||||
for (VirtualFile root : dataPack.getLogProviders().keySet()) {
|
||||
result.addAll(filter.getFiles(root));
|
||||
Collection<VirtualFile> files = filter.getFiles(root);
|
||||
result.addAll(files);
|
||||
if (files.isEmpty() && filter.getRoots().contains(root)) {
|
||||
result.add(root);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -107,11 +111,10 @@ class StructureFilterPopupComponent extends FilterPopupComponent<VcsLogStructure
|
||||
VcsLogDataPack dataPack = myFilterModel.getDataPack();
|
||||
VcsLogStructureFilter filter = myFilterModel.getFilter();
|
||||
Collection<VirtualFile> files = filter == null ? Collections.<VirtualFile>emptySet() : getAllFiles(dataPack, filter);
|
||||
Set<VirtualFile> roots = dataPack.getLogProviders().keySet();
|
||||
VcsStructureChooser chooser = new VcsStructureChooser(project, "Select Files or Folders to Filter", files,
|
||||
new ArrayList<VirtualFile>(roots));
|
||||
new ArrayList<VirtualFile>(dataPack.getLogProviders().keySet()));
|
||||
if (chooser.showAndGet()) {
|
||||
myFilterModel.setFilter(new VcsLogStructureFilterImpl(chooser.getSelectedFiles(), roots));
|
||||
myFilterModel.setFilter(VcsLogStructureFilterImpl.build(chooser.getSelectedFiles(), dataPack));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -440,10 +440,13 @@ public class GitLogProvider implements VcsLogProvider {
|
||||
|
||||
// note: structure filter must be the last parameter, because it uses "--" which separates parameters from paths
|
||||
if (filterCollection.getStructureFilter() != null) {
|
||||
filterParameters.add("--simplify-merges");
|
||||
filterParameters.add("--");
|
||||
for (VirtualFile file : filterCollection.getStructureFilter().getFiles(root)) {
|
||||
filterParameters.add(file.getPath());
|
||||
Collection<VirtualFile> files = filterCollection.getStructureFilter().getFiles(root);
|
||||
if (!files.isEmpty()) {
|
||||
filterParameters.add("--simplify-merges");
|
||||
filterParameters.add("--");
|
||||
for (VirtualFile file : files) {
|
||||
filterParameters.add(file.getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user