diff options
Diffstat (limited to 'platform/vcs-log')
21 files changed, 380 insertions, 281 deletions
diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogProvider.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogProvider.java index 89805947869c..d9c72314edbc 100644 --- a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogProvider.java +++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogProvider.java @@ -10,6 +10,7 @@ import org.jetbrains.annotations.Nullable; import java.util.Collection; import java.util.List; +import java.util.Set; /** * Provides the information needed to build the VCS log, such as the list of most recent commits with their parents. @@ -17,20 +18,26 @@ import java.util.List; public interface VcsLogProvider { /** - * Reads the most recent correctly ordered commits from the log. <br/> - * Commits should be at least topologically ordered, better considering commit time as well. <br/> - * Commits will be shown in the log in this order. - * @param requirements some limitations on commit data that should be returned. + * Reads the most recent commits from the log together with all repository references.<br/> + * Commits should be at least topologically ordered, better considering commit time as well: they will be shown in the log in this order. + * <p/> + * This method is called both on the startup and on refresh. + * + * @param requirements some limitations on commit data that should be returned, e.g. the number of commits. + * @return given amount of ordered commits and <b>all</b> references in the repository. */ @NotNull - List<? extends VcsCommitMetadata> readFirstBlock(@NotNull VirtualFile root, @NotNull Requirements requirements) throws VcsException; + DetailedLogData readFirstBlock(@NotNull VirtualFile root, @NotNull Requirements requirements) throws VcsException; /** - * <p>Reads the whole history, but only hashes & parents.</p> - * <p>Also reports authors/committers of this repository to the given user registry.</p> + * Reads the whole history. + * <p/> + * Reports commits to the consumer to avoid creation & even temporary storage of a too large commits collection. + * + * @return all references and all authors in the repository. */ - void readAllHashes(@NotNull VirtualFile root, @NotNull Consumer<VcsUser> userRegistry, - @NotNull Consumer<TimedVcsCommit> commitConsumer) throws VcsException; + @NotNull + LogData readAllHashes(@NotNull VirtualFile root, @NotNull Consumer<TimedVcsCommit> commitConsumer) throws VcsException; /** * Reads those details of the given commits, which are necessary to be shown in the log table. @@ -45,12 +52,6 @@ public interface VcsLogProvider { List<? extends VcsFullCommitDetails> readFullDetails(@NotNull VirtualFile root, @NotNull List<String> hashes) throws VcsException; /** - * Read all references (branches, tags, etc.) for the given roots. - */ - @NotNull - Collection<VcsRef> readAllRefs(@NotNull VirtualFile root) throws VcsException; - - /** * <p>Returns the VCS which is supported by this provider.</p> * <p>If there will be several VcsLogProviders which support the same VCS, only one will be chosen. It is undefined, which one.</p> */ @@ -106,4 +107,20 @@ public interface VcsLogProvider { } + /** + * Container for references and users. + */ + interface LogData { + @NotNull Set<VcsRef> getRefs(); + @NotNull Set<VcsUser> getUsers(); + } + + /** + * Container for the ordered list of commits together with their details, and references. + */ + interface DetailedLogData { + @NotNull List<VcsCommitMetadata> getCommits(); + @NotNull Set<VcsRef> getRefs(); + } + } diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogProviderRequirementsEx.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogProviderRequirementsEx.java index d69579ac00b1..68623a6852f9 100644 --- a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogProviderRequirementsEx.java +++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogProviderRequirementsEx.java @@ -15,7 +15,6 @@ */ package com.intellij.vcs.log; -import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.NotNull; import java.util.Set; @@ -24,7 +23,7 @@ import static com.intellij.vcs.log.VcsLogProvider.Requirements; /** * Extension of the standard {@link Requirements} which contains data used by some VCSs. <br/> - * An object of this object is actually passed to {@link VcsLogProvider#readFirstBlock(VirtualFile, Requirements)}, but VcsLogProviders + * An object of this object is actually passed to {@link #readFirstBlock(com.intellij.util.Consumer}, but VcsLogProviders * which need this additional information must check for instanceof before casting & be able to fallback. */ public interface VcsLogProviderRequirementsEx extends Requirements { @@ -41,10 +40,4 @@ public interface VcsLogProviderRequirementsEx extends Requirements { @NotNull Set<VcsRef> getPreviousRefs(); - /** - * Returns current refs. - */ - @NotNull - Set<VcsRef> getCurrentRefs(); - } diff --git a/platform/vcs-log/api/vcs-log-api.iml b/platform/vcs-log/api/vcs-log-api.iml index 92d746615afa..a9a76e60b302 100644 --- a/platform/vcs-log/api/vcs-log-api.iml +++ b/platform/vcs-log/api/vcs-log-api.iml @@ -10,7 +10,6 @@ <orderEntry type="module" module-name="util-rt" /> <orderEntry type="module" module-name="vcs-log-graph-api" exported="" /> <orderEntry type="module" module-name="core-api" /> - <orderEntry type="library" name="JUnit4" level="project" /> <orderEntry type="module" module-name="vcs-api-core" /> <orderEntry type="module" module-name="editor-ui-api" /> </component> diff --git a/platform/vcs-log/graph-api/src/com/intellij/vcs/log/graph/RowInfo.java b/platform/vcs-log/graph-api/src/com/intellij/vcs/log/graph/RowInfo.java index 3855467bffad..15a6cb07895d 100644 --- a/platform/vcs-log/graph-api/src/com/intellij/vcs/log/graph/RowInfo.java +++ b/platform/vcs-log/graph-api/src/com/intellij/vcs/log/graph/RowInfo.java @@ -32,4 +32,7 @@ public interface RowInfo<CommitId> { @NotNull Collection<PrintElement> getPrintElements(); + @NotNull + RowType getRowType(); + } diff --git a/platform/vcs-log/graph-api/src/com/intellij/vcs/log/graph/RowType.java b/platform/vcs-log/graph-api/src/com/intellij/vcs/log/graph/RowType.java new file mode 100644 index 000000000000..b1deca566e0d --- /dev/null +++ b/platform/vcs-log/graph-api/src/com/intellij/vcs/log/graph/RowType.java @@ -0,0 +1,27 @@ +/* + * 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. + * 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.vcs.log.graph; + +public enum RowType { + + NORMAL, + + /** + * Indicates that the commit on this row doesn't match current filters. + */ + UNMATCHED + +} diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/AbstractVisibleGraph.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/AbstractVisibleGraph.java index 83cb53fd8c8f..315371192065 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/AbstractVisibleGraph.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/AbstractVisibleGraph.java @@ -105,6 +105,12 @@ public abstract class AbstractVisibleGraph<CommitId> implements VisibleGraph<Com public Collection<PrintElement> getPrintElements() { return myPrintElementGenerator.getPrintElements(visibleRow); } + + @NotNull + @Override + public RowType getRowType() { + return RowType.NORMAL; + } }; } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/DataPack.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/DataPack.java index 48b25be01ab9..975808611ed4 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/DataPack.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/DataPack.java @@ -26,16 +26,14 @@ public class DataPack implements VcsLogDataPack { private boolean myFull; @NotNull - static DataPack build(@NotNull List<? extends GraphCommit<Integer>> commits, @NotNull RefsModel refsModel, - @NotNull NotNullFunction<Hash, Integer> indexGetter, @NotNull NotNullFunction<Integer, Hash> hashGetter, - @NotNull Map<VirtualFile, VcsLogProvider> providers, boolean full) { - return build(buildPermanentGraph(commits, refsModel, indexGetter, hashGetter, providers), providers, refsModel, full); - } - - @NotNull - static DataPack build(@NotNull PermanentGraph<Integer> permanentGraph, @NotNull Map<VirtualFile, VcsLogProvider> providers, - @NotNull RefsModel refsModel, boolean full) { - return new DataPack(refsModel, permanentGraph, createGraphFacade(permanentGraph), providers, full); + static DataPack build(@NotNull List<? extends GraphCommit<Integer>> commits, + @NotNull Map<VirtualFile, Set<VcsRef>> refs, + @NotNull Map<VirtualFile, VcsLogProvider> providers, + @NotNull VcsLogHashMap hashMap, + boolean full) { + RefsModel refsModel = new RefsModel(refs, hashMap.asIndexGetter()); + PermanentGraph<Integer> graph = buildPermanentGraph(commits, refsModel, hashMap.asIndexGetter(), hashMap.asHashGetter(), providers); + return new DataPack(refsModel, graph, createGraphFacade(graph), providers, full); } @NotNull @@ -57,11 +55,11 @@ public class DataPack implements VcsLogDataPack { } @NotNull - static PermanentGraph<Integer> buildPermanentGraph(@NotNull List<? extends GraphCommit<Integer>> commits, - @NotNull RefsModel refsModel, - @NotNull NotNullFunction<Hash, Integer> indexGetter, - @NotNull NotNullFunction<Integer, Hash> hashGetter, - @NotNull Map<VirtualFile, VcsLogProvider> providers) { + private static PermanentGraph<Integer> buildPermanentGraph(@NotNull List<? extends GraphCommit<Integer>> commits, + @NotNull RefsModel refsModel, + @NotNull NotNullFunction<Hash, Integer> indexGetter, + @NotNull NotNullFunction<Integer, Hash> hashGetter, + @NotNull Map<VirtualFile, VcsLogProvider> providers) { if (commits.isEmpty()) { return EmptyPermanentGraph.getInstance(); } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/EmptyDataPack.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/EmptyDataPack.java index 6262d767d071..54140afb3940 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/EmptyDataPack.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/EmptyDataPack.java @@ -22,14 +22,14 @@ import com.intellij.vcs.log.VcsLogProvider; import com.intellij.vcs.log.VcsRef; import org.jetbrains.annotations.NotNull; -import java.util.Collection; import java.util.Collections; +import java.util.Set; public class EmptyDataPack { @NotNull public static DataPack getInstance() { - RefsModel emptyModel = new RefsModel(Collections.<VirtualFile, Collection<VcsRef>>emptyMap(), new ConstantFunction<Hash, Integer>(0)); + RefsModel emptyModel = new RefsModel(Collections.<VirtualFile, Set<VcsRef>>emptyMap(), new ConstantFunction<Hash, Integer>(0)); return new DataPack(emptyModel, EmptyPermanentGraph.getInstance(), new EmptyGraphFacade(), Collections.<VirtualFile, VcsLogProvider>emptyMap(), false); } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/EmptyVisibleGraph.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/EmptyVisibleGraph.java index 4bdd38936361..f52b37d1f021 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/EmptyVisibleGraph.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/EmptyVisibleGraph.java @@ -17,6 +17,7 @@ package com.intellij.vcs.log.data; import com.intellij.vcs.log.graph.PrintElement; import com.intellij.vcs.log.graph.RowInfo; +import com.intellij.vcs.log.graph.RowType; import com.intellij.vcs.log.graph.VisibleGraph; import com.intellij.vcs.log.graph.actions.ActionController; import com.intellij.vcs.log.graph.actions.GraphAnswer; @@ -120,5 +121,11 @@ class EmptyVisibleGraph implements VisibleGraph<Integer> { public Collection<PrintElement> getPrintElements() { return Collections.emptyList(); } + + @NotNull + @Override + public RowType getRowType() { + return RowType.NORMAL; + } } } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/RefsModel.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/RefsModel.java index 46504b338970..c38e4c315ff0 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/RefsModel.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/RefsModel.java @@ -16,14 +16,14 @@ import java.util.*; public class RefsModel implements VcsLogRefs { - @NotNull private final Map<VirtualFile, Collection<VcsRef>> myRefs; + @NotNull private final Map<VirtualFile, Set<VcsRef>> myRefs; @NotNull private final NotNullFunction<Hash, Integer> myIndexGetter; @NotNull private final Collection<VcsRef> myBranches; @NotNull private final MultiMap<Hash, VcsRef> myRefsToHashes; @NotNull private final TIntObjectHashMap<SmartList<VcsRef>> myRefsToIndices; - public RefsModel(@NotNull Map<VirtualFile, Collection<VcsRef>> refsByRoot, @NotNull NotNullFunction<Hash, Integer> indexGetter) { + public RefsModel(@NotNull Map<VirtualFile, Set<VcsRef>> refsByRoot, @NotNull NotNullFunction<Hash, Integer> indexGetter) { myRefs = refsByRoot; myIndexGetter = indexGetter; @@ -85,7 +85,7 @@ public class RefsModel implements VcsLogRefs { } @NotNull - public Map<VirtualFile, Collection<VcsRef>> getAllRefsByRoot() { + public Map<VirtualFile, Set<VcsRef>> getAllRefsByRoot() { return myRefs; } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogMultiRepoJoiner.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogMultiRepoJoiner.java index 072e0e26ace1..f36b26a74d94 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogMultiRepoJoiner.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogMultiRepoJoiner.java @@ -6,31 +6,31 @@ import org.jetbrains.annotations.NotNull; import java.util.*; -public class VcsLogMultiRepoJoiner<CommitId> { +public class VcsLogMultiRepoJoiner<CommitId, Commit extends GraphCommit<CommitId>> { @NotNull - public List<? extends GraphCommit<CommitId>> join(@NotNull Collection<List<? extends GraphCommit<CommitId>>> logsFromRepos) { + public List<Commit> join(@NotNull Collection<List<Commit>> logsFromRepos) { if (logsFromRepos.size() == 1) { return logsFromRepos.iterator().next(); } int size = 0; - for (List<? extends GraphCommit<CommitId>> repo : logsFromRepos) { + for (List<Commit> repo : logsFromRepos) { size += repo.size(); } - List<GraphCommit<CommitId>> result = new ArrayList<GraphCommit<CommitId>>(size); + List<Commit> result = new ArrayList<Commit>(size); - Map<GraphCommit<CommitId>, Iterator<? extends GraphCommit<CommitId>>> nextCommits = ContainerUtil.newHashMap(); - for (List<? extends GraphCommit<CommitId>> log : logsFromRepos) { - Iterator<? extends GraphCommit<CommitId>> iterator = log.iterator(); + Map<Commit, Iterator<Commit>> nextCommits = ContainerUtil.newHashMap(); + for (List<Commit> log : logsFromRepos) { + Iterator<Commit> iterator = log.iterator(); if (iterator.hasNext()) { nextCommits.put(iterator.next(), iterator); } } while (!nextCommits.isEmpty()) { - GraphCommit<CommitId> lastCommit = findLatestCommit(nextCommits.keySet()); - Iterator<? extends GraphCommit<CommitId>> iterator = nextCommits.get(lastCommit); + Commit lastCommit = findLatestCommit(nextCommits.keySet()); + Iterator<Commit> iterator = nextCommits.get(lastCommit); result.add(lastCommit); nextCommits.remove(lastCommit); @@ -43,10 +43,10 @@ public class VcsLogMultiRepoJoiner<CommitId> { } @NotNull - private GraphCommit<CommitId> findLatestCommit(@NotNull Set<GraphCommit<CommitId>> commits) { + private Commit findLatestCommit(@NotNull Set<Commit> commits) { long maxTimeStamp = Long.MIN_VALUE; - GraphCommit<CommitId> lastCommit = null; - for (GraphCommit<CommitId> commit : commits) { + Commit lastCommit = null; + for (Commit commit : commits) { if (commit.getTimestamp() >= maxTimeStamp) { maxTimeStamp = commit.getTimestamp(); lastCommit = commit; diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefresherImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefresherImpl.java index c7ab5e324b3d..09de51c722bf 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefresherImpl.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefresherImpl.java @@ -27,6 +27,7 @@ import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.Consumer; import com.intellij.util.Function; +import com.intellij.util.NotNullFunction; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.UIUtil; import com.intellij.vcs.log.*; @@ -62,7 +63,8 @@ public class VcsLogRefresherImpl implements VcsLogRefresher { @NotNull final VcsUserRegistryImpl userRegistry, @NotNull Map<Hash, VcsCommitMetadata> topCommitsDetailsCache, @NotNull final Consumer<DataPack> dataPackUpdateHandler, - @NotNull Consumer<Exception> exceptionHandler, int recentCommitsCount) { + @NotNull Consumer<Exception> exceptionHandler, + int recentCommitsCount) { myProject = project; myHashMap = hashMap; myProviders = providers; @@ -95,16 +97,11 @@ public class VcsLogRefresherImpl implements VcsLogRefresher { @Override public DataPack readFirstBlock() { try { - Map<VirtualFile, Collection<VcsRef>> refs = loadRefsFromVcs(myProviders); - Set<VirtualFile> roots = myProviders.keySet(); - Map<VirtualFile, VcsLogProvider.Requirements> requirements = prepareSimpleRequirements(roots, myRecentCommitCount); - Map<VirtualFile, List<? extends GraphCommit<Integer>>> commits = loadRecentCommitsFromVcs(myProviders, requirements, - myUserRegistry, myTopCommitsDetailsCache, - myHashMap); - List<? extends GraphCommit<Integer>> compoundLog = compound(commits.values()); - DataPack dataPack = DataPack.build(compoundLog, new RefsModel(refs, myHashMap.asIndexGetter()), - myHashMap.asIndexGetter(), myHashMap.asHashGetter(), myProviders, false); - mySingleTaskController.request(RefreshRequest.RELOAD_ALL); // build/rebuild the full log in bg + LogInfo data = loadRecentData(new CommitCountRequirements(myRecentCommitCount).asMap(myProviders.keySet())); + Collection<List<GraphCommit<Integer>>> commits = data.getCommits(); + Map<VirtualFile, Set<VcsRef>> refs = data.getRefs(); + DataPack dataPack = DataPack.build(multiRepoJoin(commits), refs, myProviders, myHashMap, false); + mySingleTaskController.request(RefreshRequest.RELOAD_ALL); // build/rebuild the full log in background return dataPack; } catch (VcsException e) { @@ -113,109 +110,77 @@ public class VcsLogRefresherImpl implements VcsLogRefresher { } } - @Override - public void refresh(@NotNull Collection<VirtualFile> rootsToRefresh) { - if (!rootsToRefresh.isEmpty()) { - mySingleTaskController.request(new RefreshRequest(rootsToRefresh)); - } - } - @NotNull - private static Map<VirtualFile, VcsLogProvider.Requirements> prepareSimpleRequirements(@NotNull Collection<VirtualFile> roots, - final int commitCount) { - final VcsLogProvider.Requirements requirements = new VcsLogProvider.Requirements() { - @Override - public int getCommitCount() { - return commitCount; - } - }; - return ContainerUtil.map2Map(roots, new Function<VirtualFile, Pair<VirtualFile, VcsLogProvider.Requirements>>() { - @Override - public Pair<VirtualFile, VcsLogProvider.Requirements> fun(VirtualFile file) { - return Pair.create(file, requirements); - } - }); - } - - @NotNull - private static Map<VirtualFile, Collection<VcsRef>> loadRefsFromVcs(@NotNull Map<VirtualFile, VcsLogProvider> providers) - throws VcsException { - final StopWatch sw = StopWatch.start("loading refs"); - final Map<VirtualFile, Collection<VcsRef>> refs = ContainerUtil.newHashMap(); + private LogInfo loadRecentData(@NotNull final Map<VirtualFile, VcsLogProvider.Requirements> requirements) throws VcsException { + final StopWatch sw = StopWatch.start("loading commits"); + final LogInfo logInfo = new LogInfo(); new ProviderIterator() { @Override - void each(@NotNull VirtualFile root, @NotNull VcsLogProvider provider) throws VcsException { - refs.put(root, provider.readAllRefs(root)); + public void each(@NotNull VirtualFile root, @NotNull VcsLogProvider provider) throws VcsException { + VcsLogProvider.DetailedLogData data = provider.readFirstBlock(root, requirements.get(root)); + storeUsersAndDetails(data.getCommits()); + logInfo.put(root, compactCommits(data.getCommits())); + logInfo.put(root, data.getRefs()); sw.rootCompleted(root); } - }.iterate(providers); + }.iterate(getProvidersForRoots(requirements.keySet())); + myUserRegistry.flush(); sw.report(); - return refs; + return logInfo; } @NotNull - private static Map<VirtualFile, List<? extends GraphCommit<Integer>>> loadRecentCommitsFromVcs( - @NotNull Map<VirtualFile, VcsLogProvider> providers, - @NotNull final Map<VirtualFile, VcsLogProvider.Requirements> requirements, - @NotNull final VcsUserRegistryImpl userRegistry, - @NotNull final Map<Hash, VcsCommitMetadata> topCommitsDetailsCache, - @NotNull final VcsLogHashMap hashMap) throws VcsException - { - final StopWatch sw = StopWatch.start("loading commits"); - final Map<VirtualFile, List<? extends GraphCommit<Integer>>> commits = ContainerUtil.newHashMap(); - new ProviderIterator() { - @Override - public void each(@NotNull VirtualFile root, @NotNull VcsLogProvider provider) throws VcsException { - List<? extends VcsCommitMetadata> metadatas = provider.readFirstBlock(root, requirements.get(root)); - storeUsersAndDetails(metadatas, userRegistry, topCommitsDetailsCache); - commits.put(root, compactCommits(metadatas, hashMap)); - sw.rootCompleted(root); - } - }.iterate(providers); - userRegistry.flush(); - sw.report(); - return commits; + private Map<VirtualFile, VcsLogProvider> getProvidersForRoots(@NotNull Set<VirtualFile> roots) { + return ContainerUtil.map2Map(roots, + new Function<VirtualFile, Pair<VirtualFile, VcsLogProvider>>() { + @Override + public Pair<VirtualFile, VcsLogProvider> fun(VirtualFile root) { + return Pair.create(root, myProviders.get(root)); + } + }); + } + + @Override + public void refresh(@NotNull Collection<VirtualFile> rootsToRefresh) { + if (!rootsToRefresh.isEmpty()) { + mySingleTaskController.request(new RefreshRequest(rootsToRefresh)); + } } - /** - * Compounds logs from different repositories into a single multi-repository log. - */ @NotNull - private static List<? extends GraphCommit<Integer>> compound(@NotNull Collection<List<? extends GraphCommit<Integer>>> commits) { + private static <T extends GraphCommit<Integer>> List<T> multiRepoJoin(@NotNull Collection<List<T>> commits) { StopWatch sw = StopWatch.start("multi-repo join"); - List<? extends GraphCommit<Integer>> joined = new VcsLogMultiRepoJoiner<Integer>().join(commits); + List<T> joined = new VcsLogMultiRepoJoiner<Integer, T>().join(commits); sw.report(); return joined; } @NotNull - private static List<GraphCommit<Integer>> compactCommits(@NotNull List<? extends TimedVcsCommit> commits, - @NotNull final VcsLogHashMap hashMap) { + private List<GraphCommit<Integer>> compactCommits(@NotNull List<? extends TimedVcsCommit> commits) { StopWatch sw = StopWatch.start("compacting commits"); List<GraphCommit<Integer>> map = ContainerUtil.map(commits, new Function<TimedVcsCommit, GraphCommit<Integer>>() { @NotNull @Override public GraphCommit<Integer> fun(@NotNull TimedVcsCommit commit) { - return compactCommit(commit, hashMap); + return compactCommit(commit); } }); - hashMap.flush(); + myHashMap.flush(); sw.report(); return map; } @NotNull - private static GraphCommitImpl<Integer> compactCommit(@NotNull TimedVcsCommit commit, @NotNull VcsLogHashMap hashMap) { - return new GraphCommitImpl<Integer>(hashMap.getCommitIndex(commit.getId()), - ContainerUtil.map(commit.getParents(), hashMap.asIndexGetter()), commit.getTimestamp()); + private GraphCommitImpl<Integer> compactCommit(@NotNull TimedVcsCommit commit) { + return new GraphCommitImpl<Integer>(myHashMap.getCommitIndex(commit.getId()), + ContainerUtil.map(commit.getParents(), myHashMap.asIndexGetter()), commit.getTimestamp()); } - private static void storeUsersAndDetails(@NotNull List<? extends VcsCommitMetadata> metadatas, @NotNull VcsUserRegistryImpl userRegistry, - @NotNull Map<Hash, VcsCommitMetadata> topCommitsDetailsCache) { + private void storeUsersAndDetails(@NotNull Collection<? extends VcsCommitMetadata> metadatas) { for (VcsCommitMetadata detail : metadatas) { - userRegistry.addUser(detail.getAuthor()); - userRegistry.addUser(detail.getCommitter()); - topCommitsDetailsCache.put(detail.getId(), detail); + myUserRegistry.addUser(detail.getAuthor()); + myUserRegistry.addUser(detail.getCommitter()); + myTopCommitsDetailsCache.put(detail.getId(), detail); } } @@ -223,17 +188,7 @@ public class VcsLogRefresherImpl implements VcsLogRefresher { @NotNull private DataPack myCurrentDataPack; - // collects loaded info from different roots, which refresh was requested consecutively within a single task - private final Map<VirtualFile, LogAndRefs> myLoadedInfos = ContainerUtil.newHashMap(); - - private class LogAndRefs { - List<? extends GraphCommit<Integer>> log; - Collection<VcsRef> refs; - LogAndRefs(Collection<VcsRef> refs, List<? extends GraphCommit<Integer>> commits) { - this.refs = refs; - this.log = commits; - } - } + @NotNull private final LogInfo myLoadedInfo = new LogInfo(); MyRefreshTask(@NotNull DataPack currentDataPack) { super(VcsLogRefresherImpl.this.myProject, "Refreshing history...", false); @@ -271,30 +226,28 @@ public class VcsLogRefresherImpl implements VcsLogRefresher { private DataPack doRefresh(@NotNull Collection<VirtualFile> roots) { StopWatch sw = StopWatch.start("refresh"); PermanentGraph<Integer> permanentGraph = myCurrentDataPack.isFull() ? myCurrentDataPack.getPermanentGraph() : null; - Map<VirtualFile, Collection<VcsRef>> currentRefs = myCurrentDataPack.getRefsModel().getAllRefsByRoot(); + Map<VirtualFile, Set<VcsRef>> currentRefs = myCurrentDataPack.getRefsModel().getAllRefsByRoot(); try { if (permanentGraph != null) { int commitCount = myRecentCommitCount; for (int attempt = 0; attempt <= 1; attempt++) { loadLogAndRefs(roots, currentRefs, commitCount); - List<? extends GraphCommit<Integer>> compoundLog = compoundLoadedLogs(myLoadedInfos.values()); - Map<VirtualFile, Collection<VcsRef>> allNewRefs = getAllNewRefs(myLoadedInfos, currentRefs); + List<? extends GraphCommit<Integer>> compoundLog = multiRepoJoin(myLoadedInfo.getCommits()); + Map<VirtualFile, Set<VcsRef>> allNewRefs = getAllNewRefs(myLoadedInfo, currentRefs); List<GraphCommit<Integer>> joinedFullLog = join(compoundLog, permanentGraph.getAllCommits(), currentRefs, allNewRefs); if (joinedFullLog == null) { commitCount *= 5; } else { - return DataPack.build(joinedFullLog, new RefsModel(allNewRefs, myHashMap.asIndexGetter()), - myHashMap.asIndexGetter(), myHashMap.asHashGetter(), myProviders, true); + return DataPack.build(joinedFullLog, allNewRefs, myProviders, myHashMap, true); } } // couldn't join => need to reload everything; if 5000 commits is still not enough, it's worth reporting: LOG.error("Couldn't join " + commitCount + " recent commits to the log (" + permanentGraph.getAllCommits().size() + " commits)", - new Attachment("recent_commits", toLogString(myLoadedInfos))); + new Attachment("recent_commits", myLoadedInfo.toLogString(myHashMap.asIndexGetter()))); } - Pair<PermanentGraph<Integer>, Map<VirtualFile, Collection<VcsRef>>> fullLogAndRefs = loadFullLog(); - return DataPack.build(fullLogAndRefs.first, myProviders, new RefsModel(fullLogAndRefs.second, myHashMap.asIndexGetter()), true); + return loadFullLog(); } catch (Exception e) { myExceptionHandler.consume(e); @@ -305,95 +258,45 @@ public class VcsLogRefresherImpl implements VcsLogRefresher { } } - private String toLogString(Map<VirtualFile, LogAndRefs> infos) { - StringBuilder sb = new StringBuilder(); - for (Map.Entry<VirtualFile, LogAndRefs> entry : infos.entrySet()) { - sb.append(entry.getKey().getName()); - sb.append(" LOG:\n"); - sb.append(StringUtil.join(entry.getValue().log, new Function<GraphCommit<Integer>, String>() { - @Override - public String fun(GraphCommit<Integer> commit) { - return commit.getId() + "<-" + StringUtil.join(commit.getParents(), ","); - } - }, "\n")); - sb.append("\nREFS:\n"); - sb.append(StringUtil.join(entry.getValue().refs, new Function<VcsRef, String>() { - @Override - public String fun(VcsRef ref) { - return ref.getName() + "(" + myHashMap.getCommitIndex(ref.getCommitHash()) + ")"; - } - }, ",")); - } - return sb.toString(); - } - @NotNull - private List<? extends GraphCommit<Integer>> compoundLoadedLogs(@NotNull Collection<LogAndRefs> logsAndRefs) { - return compound(ContainerUtil.map(logsAndRefs, new Function<LogAndRefs, List<? extends GraphCommit<Integer>>>() { - @Override - public List<? extends GraphCommit<Integer>> fun(LogAndRefs refs) { - return refs.log; - } - })); - } - - @NotNull - private Map<VirtualFile, Collection<VcsRef>> getAllNewRefs(@NotNull Map<VirtualFile, LogAndRefs> newInfo, - @NotNull Map<VirtualFile, Collection<VcsRef>> previousRefs) { - Map<VirtualFile, Collection<VcsRef>> result = ContainerUtil.newHashMap(); + private Map<VirtualFile, Set<VcsRef>> getAllNewRefs(@NotNull LogInfo newInfo, + @NotNull Map<VirtualFile, Set<VcsRef>> previousRefs) { + Map<VirtualFile, Set<VcsRef>> result = ContainerUtil.newHashMap(); for (VirtualFile root : previousRefs.keySet()) { - result.put(root, newInfo.containsKey(root) ? newInfo.get(root).refs : previousRefs.get(root)); + Set<VcsRef> newInfoRefs = newInfo.getRefs(root); + result.put(root, newInfoRefs != null ? newInfoRefs : previousRefs.get(root)); } return result; } - private void loadLogAndRefs(@NotNull Collection<VirtualFile> roots, @NotNull Map<VirtualFile, Collection<VcsRef>> prevRefs, + private void loadLogAndRefs(@NotNull Collection<VirtualFile> roots, + @NotNull Map<VirtualFile, Set<VcsRef>> prevRefs, int commitCount) throws VcsException { - Map<VirtualFile, VcsLogProvider> providers = getProviders(roots); - Map<VirtualFile, Collection<VcsRef>> refs = loadRefsFromVcs(providers); - Map<VirtualFile, VcsLogProvider.Requirements> requirements = prepareRequirements(roots, commitCount, prevRefs, refs); - Map<VirtualFile, List<? extends GraphCommit<Integer>>> commits = loadRecentCommitsFromVcs(providers, requirements, - myUserRegistry, myTopCommitsDetailsCache, - myHashMap); + LogInfo logInfo = loadRecentData(prepareRequirements(roots, commitCount, prevRefs)); for (VirtualFile root : roots) { - myLoadedInfos.put(root, new LogAndRefs(refs.get(root), commits.get(root))); + myLoadedInfo.put(root, logInfo.getCommits(root)); + myLoadedInfo.put(root, logInfo.getRefs(root)); } } @NotNull private Map<VirtualFile, VcsLogProvider.Requirements> prepareRequirements(@NotNull Collection<VirtualFile> roots, int commitCount, - @NotNull Map<VirtualFile, Collection<VcsRef>> prevRefs, - @NotNull Map<VirtualFile, Collection<VcsRef>> newRefs) { + @NotNull Map<VirtualFile, Set<VcsRef>> prevRefs) { Map<VirtualFile, VcsLogProvider.Requirements> requirements = ContainerUtil.newHashMap(); for (VirtualFile root : roots) { - requirements.put(root, new RequirementsImpl(commitCount, true, getRefsForRoot(prevRefs, root), getRefsForRoot(newRefs, root))); + requirements.put(root, new RequirementsImpl(commitCount, true, ContainerUtil.notNullize(prevRefs.get(root)))); } return requirements; } - @NotNull - private Set<VcsRef> getRefsForRoot(@NotNull Map<VirtualFile, Collection<VcsRef>> map, @NotNull VirtualFile root) { - Collection<VcsRef> refs = map.get(root); - return refs == null ? Collections.<VcsRef>emptySet() : new HashSet<VcsRef>(refs); - } - - @NotNull - private Map<VirtualFile, VcsLogProvider> getProviders(@NotNull Collection<VirtualFile> roots) { - Map<VirtualFile, VcsLogProvider> providers = ContainerUtil.newHashMap(); - for (VirtualFile root : roots) { - providers.put(root, myProviders.get(root)); - } - return providers; - } - @Nullable - private List<GraphCommit<Integer>> join(@NotNull List<? extends GraphCommit<Integer>> recentCommits, @NotNull List<GraphCommit<Integer>> fullLog, - @NotNull Map<VirtualFile, Collection<VcsRef>> previousRefs, - @NotNull Map<VirtualFile, Collection<VcsRef>> newRefs) { + private List<GraphCommit<Integer>> join(@NotNull List<? extends GraphCommit<Integer>> recentCommits, + @NotNull List<GraphCommit<Integer>> fullLog, + @NotNull Map<VirtualFile, Set<VcsRef>> previousRefs, + @NotNull Map<VirtualFile, Set<VcsRef>> newRefs) { StopWatch sw = StopWatch.start("joining new commits"); Function<VcsRef, Integer> ref2Int = new Function<VcsRef, Integer>() { - @NotNull @Override public Integer fun(@NotNull VcsRef ref) { return myHashMap.getCommitIndex(ref.getCommitHash()); @@ -418,50 +321,44 @@ public class VcsLogRefresherImpl implements VcsLogRefresher { } @NotNull - private Pair<PermanentGraph<Integer>, Map<VirtualFile, Collection<VcsRef>>> loadFullLog() throws VcsException { + private DataPack loadFullLog() throws VcsException { StopWatch sw = StopWatch.start("full log reload"); - Collection<List<? extends GraphCommit<Integer>>> commits = readFullLogFromVcs(); - List<? extends GraphCommit<Integer>> graphCommits = compound(commits); - Map<VirtualFile, Collection<VcsRef>> refMap = loadRefsFromVcs(myProviders); - PermanentGraph<Integer> permanentGraph = DataPack.buildPermanentGraph(graphCommits, new RefsModel(refMap, myHashMap.asIndexGetter()), - myHashMap.asIndexGetter(), - myHashMap.asHashGetter(), myProviders); + LogInfo logInfo = readFullLogFromVcs(); + List<? extends GraphCommit<Integer>> graphCommits = multiRepoJoin(logInfo.getCommits()); + DataPack dataPack = DataPack.build(graphCommits, logInfo.getRefs(), myProviders, myHashMap, true); sw.report(); - return Pair.create(permanentGraph, refMap); + return dataPack; } @NotNull - private Collection<List<? extends GraphCommit<Integer>>> readFullLogFromVcs() throws VcsException { + private LogInfo readFullLogFromVcs() throws VcsException { final StopWatch sw = StopWatch.start("read full log from VCS"); - final Collection<List<? extends GraphCommit<Integer>>> logs = ContainerUtil.newArrayList(); + final LogInfo logInfo = new LogInfo(); new ProviderIterator() { @Override void each(@NotNull VirtualFile root, @NotNull VcsLogProvider provider) throws VcsException { final List<GraphCommit<Integer>> graphCommits = ContainerUtil.newArrayList(); - provider.readAllHashes(root, new Consumer<VcsUser>() { - @Override - public void consume(@NotNull VcsUser user) { - myUserRegistry.addUser(user); - } - }, new Consumer<TimedVcsCommit>() { + VcsLogProvider.LogData data = provider.readAllHashes(root, new Consumer<TimedVcsCommit>() { @Override - public void consume(TimedVcsCommit commit) { - graphCommits.add(compactCommit(commit, myHashMap)); + public void consume(@NotNull TimedVcsCommit commit) { + graphCommits.add(compactCommit(commit)); } }); - logs.add(graphCommits); + logInfo.put(root, graphCommits); + logInfo.put(root, data.getRefs()); + myUserRegistry.addUsers(data.getUsers()); sw.rootCompleted(root); } }.iterate(myProviders); myUserRegistry.flush(); sw.report(); - return logs; + return logInfo; } } private static class RefreshRequest { - private static RefreshRequest RELOAD_ALL = new RefreshRequest(Collections.<VirtualFile>emptyList()); - @NotNull private final Collection<VirtualFile> rootsToRefresh; + private static final RefreshRequest RELOAD_ALL = new RefreshRequest(Collections.<VirtualFile>emptyList()); + private final Collection<VirtualFile> rootsToRefresh; RefreshRequest(@NotNull Collection<VirtualFile> rootsToRefresh) { this.rootsToRefresh = rootsToRefresh; @@ -477,4 +374,85 @@ public class VcsLogRefresherImpl implements VcsLogRefresher { } } } + + private static class CommitCountRequirements implements VcsLogProvider.Requirements { + private final int myCommitCount; + + public CommitCountRequirements(int commitCount) { + myCommitCount = commitCount; + } + + @Override + public int getCommitCount() { + return myCommitCount; + } + + @NotNull + Map<VirtualFile, VcsLogProvider.Requirements> asMap(@NotNull Collection<VirtualFile> roots) { + return ContainerUtil.map2Map(roots, new Function<VirtualFile, Pair<VirtualFile, VcsLogProvider.Requirements>>() { + @Override + public Pair<VirtualFile, VcsLogProvider.Requirements> fun(VirtualFile root) { + return Pair.<VirtualFile, VcsLogProvider.Requirements>create(root, CommitCountRequirements.this); + } + }); + } + } + + private static class LogInfo { + private final Map<VirtualFile, Set<VcsRef>> myRefs = ContainerUtil.newHashMap(); + private final Map<VirtualFile, List<GraphCommit<Integer>>> myCommits = ContainerUtil.newHashMap(); + + void put(@NotNull VirtualFile root, @NotNull List<GraphCommit<Integer>> commits) { + myCommits.put(root, commits); + } + + void put(@NotNull VirtualFile root, @NotNull Set<VcsRef> refs) { + myRefs.put(root, refs); + } + + @NotNull + Collection<List<GraphCommit<Integer>>> getCommits() { + return myCommits.values(); + } + + List<GraphCommit<Integer>> getCommits(@NotNull VirtualFile root) { + return myCommits.get(root); + } + + @NotNull + Map<VirtualFile, Set<VcsRef>> getRefs() { + return myRefs; + } + + public Set<VcsRef> getRefs(@NotNull VirtualFile root) { + return myRefs.get(root); + } + + @SuppressWarnings("StringConcatenationInsideStringBufferAppend") + @NotNull + public String toLogString(@NotNull final NotNullFunction<Hash, Integer> indexGetter) { + StringBuilder sb = new StringBuilder(); + sb.append(" LOG:\n"); + for (Map.Entry<VirtualFile, List<GraphCommit<Integer>>> entry : myCommits.entrySet()) { + sb.append(entry.getKey().getName() + "\n"); + sb.append(StringUtil.join(entry.getValue(), new Function<GraphCommit<Integer>, String>() { + @Override + public String fun(@NotNull GraphCommit<Integer> commit) { + return commit.getId() + "<-" + StringUtil.join(commit.getParents(), ","); + } + }, "\n")); + } + sb.append("\nREFS:\n"); + for (Map.Entry<VirtualFile, Set<VcsRef>> entry : myRefs.entrySet()) { + sb.append(entry.getKey().getName() + "\n"); + sb.append(StringUtil.join(entry.getValue(), new Function<VcsRef, String>() { + @Override + public String fun(@NotNull VcsRef ref) { + return ref.getName() + "(" + indexGetter.fun(ref.getCommitHash()) + ")"; + } + }, ",")); + } + return sb.toString(); + } + } } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogSorter.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogSorter.java index d872ac236c16..3f9d742eef34 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogSorter.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogSorter.java @@ -20,12 +20,13 @@ import com.intellij.vcs.log.TimedVcsCommit; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; +import java.util.Collection; import java.util.List; public class VcsLogSorter { @NotNull - public static <Commit extends TimedVcsCommit> List<Commit> sortByDateTopoOrder(@NotNull List<Commit> commits) { + public static <Commit extends TimedVcsCommit> List<Commit> sortByDateTopoOrder(@NotNull Collection<Commit> commits) { return new VcsLogJoiner.NewCommitIntegrator<Hash, Commit>(new ArrayList<Commit>(), commits).getResultList(); } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsUserRegistryImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsUserRegistryImpl.java index a5447d20f115..8621f379ce65 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsUserRegistryImpl.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsUserRegistryImpl.java @@ -86,6 +86,12 @@ public class VcsUserRegistryImpl implements Disposable, VcsUserRegistry { } } + public void addUsers(@NotNull Collection<VcsUser> users) { + for (VcsUser user : users) { + addUser(user); + } + } + @Override @NotNull public Set<VcsUser> getUsers() { diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/LogDataImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/LogDataImpl.java new file mode 100644 index 000000000000..82eb4e1a6336 --- /dev/null +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/LogDataImpl.java @@ -0,0 +1,74 @@ +/* + * 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. + * 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.vcs.log.impl; + +import com.intellij.vcs.log.VcsCommitMetadata; +import com.intellij.vcs.log.VcsLogProvider; +import com.intellij.vcs.log.VcsRef; +import com.intellij.vcs.log.VcsUser; +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; +import java.util.List; +import java.util.Set; + +public class LogDataImpl implements VcsLogProvider.DetailedLogData, VcsLogProvider.LogData { + + private static final LogDataImpl EMPTY = new LogDataImpl(Collections.<VcsRef>emptySet(), + Collections.<VcsUser>emptySet(), + Collections.<VcsCommitMetadata>emptyList()); + + @NotNull private final List<VcsCommitMetadata> myCommits; + @NotNull private final Set<VcsRef> myRefs; + @NotNull private final Set<VcsUser> myUsers; + + @NotNull + public static LogDataImpl empty() { + return EMPTY; + } + + public LogDataImpl(@NotNull Set<VcsRef> refs, @NotNull Set<VcsUser> users) { + this(refs, users, Collections.<VcsCommitMetadata>emptyList()); + } + + public LogDataImpl(@NotNull Set<VcsRef> refs, @NotNull List<VcsCommitMetadata> metadatas) { + this(refs, Collections.<VcsUser>emptySet(), metadatas); + } + + private LogDataImpl(@NotNull Set<VcsRef> refs, @NotNull Set<VcsUser> users, @NotNull List<VcsCommitMetadata> commits) { + myRefs = refs; + myUsers = users; + myCommits = commits; + } + + @NotNull + @Override + public List<VcsCommitMetadata> getCommits() { + return myCommits; + } + + @Override + @NotNull + public Set<VcsRef> getRefs() { + return myRefs; + } + + @NotNull + @Override + public Set<VcsUser> getUsers() { + return myUsers; + } +} diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/RequirementsImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/RequirementsImpl.java index f742e277283f..9a1e54ed3886 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/RequirementsImpl.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/RequirementsImpl.java @@ -26,13 +26,11 @@ public class RequirementsImpl implements VcsLogProviderRequirementsEx { private final int myCommitCount; private final boolean myRefresh; @NotNull private final Set<VcsRef> myPreviousRefs; - @NotNull private final Set<VcsRef> myCurrentRefs; - public RequirementsImpl(int count, boolean refresh, @NotNull Set<VcsRef> previousRefs, @NotNull Set<VcsRef> currentRefs) { + public RequirementsImpl(int count, boolean refresh, @NotNull Set<VcsRef> previousRefs) { myCommitCount = count; myRefresh = refresh; myPreviousRefs = previousRefs; - myCurrentRefs = currentRefs; } @Override @@ -50,10 +48,4 @@ public class RequirementsImpl implements VcsLogProviderRequirementsEx { public Set<VcsRef> getPreviousRefs() { return myPreviousRefs; } - - @NotNull - @Override - public Set<VcsRef> getCurrentRefs() { - return myCurrentRefs; - } } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/VcsStructureChooser.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/VcsStructureChooser.java index 34c638088476..0078669cd811 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/VcsStructureChooser.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/VcsStructureChooser.java @@ -126,6 +126,7 @@ public class VcsStructureChooser extends DialogWrapper { return myModulesSet; } + @NotNull public Collection<VirtualFile> getSelectedFiles() { return ((CollectionListModel) mySelectedList.getModel()).getItems(); } diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java index c134b1aa330d..3140d647795f 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java @@ -101,7 +101,7 @@ class StructureFilterPopupComponent extends FilterPopupComponent<VcsLogStructure new ArrayList<VirtualFile>(myRoots)); if (chooser.showAndGet()) { myFiles.clear(); - myFiles.addAll(ContainerUtil.notNullize(chooser.getSelectedFiles())); + myFiles.addAll(chooser.getSelectedFiles()); setValue(myFiles); applyFilters(); } diff --git a/platform/vcs-log/impl/test/com/intellij/vcs/log/data/VcsLogRefresherTest.java b/platform/vcs-log/impl/test/com/intellij/vcs/log/data/VcsLogRefresherTest.java index 6baf2318f7a9..01705232a253 100644 --- a/platform/vcs-log/impl/test/com/intellij/vcs/log/data/VcsLogRefresherTest.java +++ b/platform/vcs-log/impl/test/com/intellij/vcs/log/data/VcsLogRefresherTest.java @@ -46,11 +46,11 @@ public class VcsLogRefresherTest extends VcsLogPlatformTest { throw new AssertionError(e); } }; - @NotNull private TestVcsLogProvider myLogProvider; - @NotNull private VcsLogDataHolder myDataHolder; - @NotNull private Map<Hash, VcsCommitMetadata> myTopDetailsCache; - @NotNull private Map<VirtualFile, VcsLogProvider> myLogProviders; - @NotNull private List<String> myCommits; + private TestVcsLogProvider myLogProvider; + private VcsLogDataHolder myDataHolder; + private Map<Hash, VcsCommitMetadata> myTopDetailsCache; + private Map<VirtualFile, VcsLogProvider> myLogProviders; + private List<String> myCommits; @Override public void setUp() throws Exception { diff --git a/platform/vcs-log/impl/test/com/intellij/vcs/log/impl/TestVcsLogProvider.java b/platform/vcs-log/impl/test/com/intellij/vcs/log/impl/TestVcsLogProvider.java index 850478b048dc..05659538da20 100644 --- a/platform/vcs-log/impl/test/com/intellij/vcs/log/impl/TestVcsLogProvider.java +++ b/platform/vcs-log/impl/test/com/intellij/vcs/log/impl/TestVcsLogProvider.java @@ -26,10 +26,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.awt.*; -import java.util.Collection; -import java.util.Comparator; +import java.util.*; import java.util.List; -import java.util.Set; import java.util.concurrent.Semaphore; import static org.junit.Assert.assertEquals; @@ -59,13 +57,14 @@ public class TestVcsLogProvider implements VcsLogProvider { @NotNull private final ReducibleSemaphore myRefreshSemaphore; private int myReadFirstBlockCounter; - private final Function<TimedVcsCommit, VcsCommitMetadata> myCommitToMetadataConvertor = new Function<TimedVcsCommit, VcsCommitMetadata>(){ - @Override - public VcsCommitMetadata fun(TimedVcsCommit commit) { - return new VcsCommitMetadataImpl(commit.getId(), commit.getParents(), commit.getTimestamp(), myRoot, SAMPLE_SUBJECT, STUB_USER, - SAMPLE_SUBJECT, STUB_USER, commit.getTimestamp()); - } - }; + private final Function<TimedVcsCommit, VcsCommitMetadata> myCommitToMetadataConvertor = + new Function<TimedVcsCommit, VcsCommitMetadata>() { + @Override + public VcsCommitMetadata fun(TimedVcsCommit commit) { + return new VcsCommitMetadataImpl(commit.getId(), commit.getParents(), commit.getTimestamp(), myRoot, + SAMPLE_SUBJECT, STUB_USER, SAMPLE_SUBJECT, STUB_USER, commit.getTimestamp()); + } + }; public TestVcsLogProvider(@NotNull VirtualFile root) { myRoot = root; @@ -78,7 +77,8 @@ public class TestVcsLogProvider implements VcsLogProvider { @NotNull @Override - public List<? extends VcsCommitMetadata> readFirstBlock(@NotNull final VirtualFile root, @NotNull Requirements requirements) + public DetailedLogData readFirstBlock(@NotNull final VirtualFile root, + @NotNull Requirements requirements) throws VcsException { if (requirements instanceof VcsLogProviderRequirementsEx && ((VcsLogProviderRequirementsEx)requirements).isRefresh()) { try { @@ -90,12 +90,14 @@ public class TestVcsLogProvider implements VcsLogProvider { } myReadFirstBlockCounter++; assertRoot(root); - return ContainerUtil.map(myCommits.subList(0, requirements.getCommitCount()), myCommitToMetadataConvertor); + List<VcsCommitMetadata> metadatas = ContainerUtil.map(myCommits.subList(0, requirements.getCommitCount()), + myCommitToMetadataConvertor); + return new LogDataImpl(Collections.<VcsRef>emptySet(), metadatas); } + @NotNull @Override - public void readAllHashes(@NotNull VirtualFile root, @NotNull Consumer<VcsUser> userRegistry, - @NotNull Consumer<TimedVcsCommit> commitConsumer) throws VcsException { + public LogData readAllHashes(@NotNull VirtualFile root, @NotNull Consumer<TimedVcsCommit> commitConsumer) throws VcsException { try { myFullLogSemaphore.acquire(); } @@ -106,6 +108,7 @@ public class TestVcsLogProvider implements VcsLogProvider { for (TimedVcsCommit commit : myCommits) { commitConsumer.consume(commit); } + return new LogDataImpl(myRefs, Collections.<VcsUser>emptySet()); } private void assertRoot(@NotNull VirtualFile root) { @@ -127,12 +130,6 @@ public class TestVcsLogProvider implements VcsLogProvider { @NotNull @Override - public Collection<VcsRef> readAllRefs(@NotNull VirtualFile root) throws VcsException { - return myRefs; - } - - @NotNull - @Override public VcsKey getSupportedVcs() { throw new UnsupportedOperationException(); } diff --git a/platform/vcs-log/impl/vcs-log-impl.iml b/platform/vcs-log/impl/vcs-log-impl.iml index 304affc03123..4fce9792f123 100644 --- a/platform/vcs-log/impl/vcs-log-impl.iml +++ b/platform/vcs-log/impl/vcs-log-impl.iml @@ -16,7 +16,7 @@ <orderEntry type="module" module-name="platform-impl" /> <orderEntry type="module" module-name="vcs-impl" /> <orderEntry type="library" name="Guava" level="project" /> - <orderEntry type="library" name="JUnit4" level="project" /> + <orderEntry type="library" scope="TEST" name="JUnit4" level="project" /> <orderEntry type="module" module-name="lang-impl" /> <orderEntry type="module" module-name="spellchecker" /> <orderEntry type="module" module-name="vcs-log-graph-api" /> |