mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[log] IDEA-125987 Consume less temporary memory when loading full log
Instead of collecting all Hash commits and then compacting them to integers, report them one by one and compact at once. Implement for Git, keep as is for Mercurial by now.
This commit is contained in:
@@ -29,8 +29,8 @@ public interface VcsLogProvider {
|
||||
* <p>Reads the whole history, but only hashes & parents.</p>
|
||||
* <p>Also reports authors/committers of this repository to the given user registry.</p>
|
||||
*/
|
||||
@NotNull
|
||||
List<TimedVcsCommit> readAllHashes(@NotNull VirtualFile root, @NotNull Consumer<VcsUser> userRegistry) throws VcsException;
|
||||
void readAllHashes(@NotNull VirtualFile root, @NotNull Consumer<VcsUser> userRegistry,
|
||||
@NotNull Consumer<TimedVcsCommit> commitConsumer) throws VcsException;
|
||||
|
||||
/**
|
||||
* Reads those details of the given commits, which are necessary to be shown in the log table.
|
||||
|
||||
@@ -1,36 +1,36 @@
|
||||
package com.intellij.vcs.log.data;
|
||||
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.vcs.log.TimedVcsCommit;
|
||||
import com.intellij.vcs.log.graph.GraphCommit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class VcsLogMultiRepoJoiner {
|
||||
public class VcsLogMultiRepoJoiner<CommitId> {
|
||||
|
||||
@NotNull
|
||||
public List<? extends TimedVcsCommit> join(@NotNull Collection<List<? extends TimedVcsCommit>> logsFromRepos) {
|
||||
public List<? extends GraphCommit<CommitId>> join(@NotNull Collection<List<? extends GraphCommit<CommitId>>> logsFromRepos) {
|
||||
if (logsFromRepos.size() == 1) {
|
||||
return logsFromRepos.iterator().next();
|
||||
}
|
||||
|
||||
int size = 0;
|
||||
for (List<? extends TimedVcsCommit> repo : logsFromRepos) {
|
||||
for (List<? extends GraphCommit<CommitId>> repo : logsFromRepos) {
|
||||
size += repo.size();
|
||||
}
|
||||
List<TimedVcsCommit> result = new ArrayList<TimedVcsCommit>(size);
|
||||
List<GraphCommit<CommitId>> result = new ArrayList<GraphCommit<CommitId>>(size);
|
||||
|
||||
Map<TimedVcsCommit, Iterator<? extends TimedVcsCommit>> nextCommits = ContainerUtil.newHashMap();
|
||||
for (List<? extends TimedVcsCommit> log : logsFromRepos) {
|
||||
Iterator<? extends TimedVcsCommit> iterator = log.iterator();
|
||||
Map<GraphCommit<CommitId>, Iterator<? extends GraphCommit<CommitId>>> nextCommits = ContainerUtil.newHashMap();
|
||||
for (List<? extends GraphCommit<CommitId>> log : logsFromRepos) {
|
||||
Iterator<? extends GraphCommit<CommitId>> iterator = log.iterator();
|
||||
if (iterator.hasNext()) {
|
||||
nextCommits.put(iterator.next(), iterator);
|
||||
}
|
||||
}
|
||||
|
||||
while (!nextCommits.isEmpty()) {
|
||||
TimedVcsCommit lastCommit = findLatestCommit(nextCommits.keySet());
|
||||
Iterator<? extends TimedVcsCommit> iterator = nextCommits.get(lastCommit);
|
||||
GraphCommit<CommitId> lastCommit = findLatestCommit(nextCommits.keySet());
|
||||
Iterator<? extends GraphCommit<CommitId>> iterator = nextCommits.get(lastCommit);
|
||||
result.add(lastCommit);
|
||||
nextCommits.remove(lastCommit);
|
||||
|
||||
@@ -43,10 +43,10 @@ public class VcsLogMultiRepoJoiner {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static TimedVcsCommit findLatestCommit(@NotNull Set<TimedVcsCommit> commits) {
|
||||
private GraphCommit<CommitId> findLatestCommit(@NotNull Set<GraphCommit<CommitId>> commits) {
|
||||
long maxTimeStamp = Long.MIN_VALUE;
|
||||
TimedVcsCommit lastCommit = null;
|
||||
for (TimedVcsCommit commit : commits) {
|
||||
GraphCommit<CommitId> lastCommit = null;
|
||||
for (GraphCommit<CommitId> commit : commits) {
|
||||
if (commit.getTimestamp() >= maxTimeStamp) {
|
||||
maxTimeStamp = commit.getTimestamp();
|
||||
lastCommit = commit;
|
||||
|
||||
@@ -96,11 +96,11 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
|
||||
Map<VirtualFile, Collection<VcsRef>> refs = loadRefsFromVcs(myProviders);
|
||||
Set<VirtualFile> roots = myProviders.keySet();
|
||||
Map<VirtualFile, VcsLogProvider.Requirements> requirements = prepareSimpleRequirements(roots, myRecentCommitCount);
|
||||
Map<VirtualFile, List<? extends TimedVcsCommit>> commits = loadRecentCommitsFromVcs(myProviders, requirements,
|
||||
myUserRegistry, myTopCommitsDetailsCache);
|
||||
List<? extends TimedVcsCommit> compoundLog = compound(commits.values());
|
||||
List<GraphCommit<Integer>> compactedLog = compactCommits(compoundLog, myHashMap);
|
||||
DataPack dataPack = DataPack.build(compactedLog, new RefsModel(refs, myHashMap.asIndexGetter()),
|
||||
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
|
||||
return dataPack;
|
||||
@@ -152,19 +152,21 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Map<VirtualFile, List<? extends TimedVcsCommit>> loadRecentCommitsFromVcs(@NotNull Map<VirtualFile, VcsLogProvider> providers,
|
||||
@NotNull final Map<VirtualFile, VcsLogProvider.Requirements> requirements,
|
||||
@NotNull final VcsUserRegistryImpl userRegistry,
|
||||
@NotNull final Map<Hash, VcsCommitMetadata> topCommitsDetailsCache)
|
||||
throws VcsException {
|
||||
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 TimedVcsCommit>> commits = ContainerUtil.newHashMap();
|
||||
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, metadatas);
|
||||
commits.put(root, compactCommits(metadatas, hashMap));
|
||||
sw.rootCompleted(root);
|
||||
}
|
||||
}.iterate(providers);
|
||||
@@ -177,9 +179,9 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
|
||||
* Compounds logs from different repositories into a single multi-repository log.
|
||||
*/
|
||||
@NotNull
|
||||
private static List<? extends TimedVcsCommit> compound(@NotNull Collection<List<? extends TimedVcsCommit>> commits) {
|
||||
private static List<? extends GraphCommit<Integer>> compound(@NotNull Collection<List<? extends GraphCommit<Integer>>> commits) {
|
||||
StopWatch sw = StopWatch.start("multi-repo join");
|
||||
List<? extends TimedVcsCommit> joined = new VcsLogMultiRepoJoiner().join(commits);
|
||||
List<? extends GraphCommit<Integer>> joined = new VcsLogMultiRepoJoiner<Integer>().join(commits);
|
||||
sw.report();
|
||||
return joined;
|
||||
}
|
||||
@@ -192,8 +194,7 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
|
||||
@NotNull
|
||||
@Override
|
||||
public GraphCommit<Integer> fun(@NotNull TimedVcsCommit commit) {
|
||||
return new GraphCommitImpl<Integer>(hashMap.getCommitIndex(commit.getId()),
|
||||
ContainerUtil.map(commit.getParents(), hashMap.asIndexGetter()), commit.getTimestamp());
|
||||
return compactCommit(commit, hashMap);
|
||||
}
|
||||
});
|
||||
hashMap.flush();
|
||||
@@ -201,6 +202,12 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
|
||||
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 static void storeUsersAndDetails(@NotNull List<? extends VcsCommitMetadata> metadatas, @NotNull VcsUserRegistryImpl userRegistry,
|
||||
@NotNull Map<Hash, VcsCommitMetadata> topCommitsDetailsCache) {
|
||||
for (VcsCommitMetadata detail : metadatas) {
|
||||
@@ -218,9 +225,9 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
|
||||
private final Map<VirtualFile, LogAndRefs> myLoadedInfos = ContainerUtil.newHashMap();
|
||||
|
||||
private class LogAndRefs {
|
||||
List<? extends TimedVcsCommit> log;
|
||||
List<? extends GraphCommit<Integer>> log;
|
||||
Collection<VcsRef> refs;
|
||||
LogAndRefs(Collection<VcsRef> refs, List<? extends TimedVcsCommit> commits) {
|
||||
LogAndRefs(Collection<VcsRef> refs, List<? extends GraphCommit<Integer>> commits) {
|
||||
this.refs = refs;
|
||||
this.log = commits;
|
||||
}
|
||||
@@ -266,16 +273,16 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
|
||||
try {
|
||||
if (permanentGraph != null) {
|
||||
loadLogAndRefs(roots, currentRefs, myRecentCommitCount);
|
||||
List<? extends TimedVcsCommit> compoundLog = compound(ContainerUtil.map(myLoadedInfos.values(),
|
||||
new Function<LogAndRefs, List<? extends TimedVcsCommit>>() {
|
||||
List<? extends GraphCommit<Integer>> compoundLog = compound(ContainerUtil.map(myLoadedInfos.values(),
|
||||
new Function<LogAndRefs, List<? extends GraphCommit<Integer>>>() {
|
||||
@Override
|
||||
public List<? extends TimedVcsCommit> fun(LogAndRefs refs) {
|
||||
public List<? extends GraphCommit<Integer>> fun(
|
||||
LogAndRefs refs) {
|
||||
return refs.log;
|
||||
}
|
||||
}));
|
||||
List<GraphCommit<Integer>> preparedLog = compactCommits(compoundLog, myHashMap);
|
||||
Map<VirtualFile, Collection<VcsRef>> allNewRefs = getAllNewRefs(myLoadedInfos, currentRefs);
|
||||
List<GraphCommit<Integer>> joinedFullLog = join(preparedLog, permanentGraph.getAllCommits(), currentRefs, allNewRefs);
|
||||
List<GraphCommit<Integer>> joinedFullLog = join(compoundLog, permanentGraph.getAllCommits(), currentRefs, allNewRefs);
|
||||
if (joinedFullLog != null) {
|
||||
return DataPack.build(joinedFullLog, new RefsModel(allNewRefs, myHashMap.asIndexGetter()),
|
||||
myHashMap.asIndexGetter(), myHashMap.asHashGetter(), myProviders, true);
|
||||
@@ -310,8 +317,9 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
|
||||
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 TimedVcsCommit>> commits = loadRecentCommitsFromVcs(providers, requirements,
|
||||
myUserRegistry, myTopCommitsDetailsCache);
|
||||
Map<VirtualFile, List<? extends GraphCommit<Integer>>> commits = loadRecentCommitsFromVcs(providers, requirements,
|
||||
myUserRegistry, myTopCommitsDetailsCache,
|
||||
myHashMap);
|
||||
for (VirtualFile root : roots) {
|
||||
myLoadedInfos.put(root, new LogAndRefs(refs.get(root), commits.get(root)));
|
||||
}
|
||||
@@ -345,7 +353,7 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private List<GraphCommit<Integer>> join(@NotNull List<GraphCommit<Integer>> recentCommits, @NotNull List<GraphCommit<Integer>> fullLog,
|
||||
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) {
|
||||
StopWatch sw = StopWatch.start("joining new commits");
|
||||
@@ -374,9 +382,8 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
|
||||
@NotNull
|
||||
private Pair<PermanentGraph<Integer>, Map<VirtualFile, Collection<VcsRef>>> loadFullLog() throws VcsException {
|
||||
StopWatch sw = StopWatch.start("full log reload");
|
||||
Collection<List<? extends TimedVcsCommit>> commits = readFullLogFromVcs();
|
||||
List<? extends TimedVcsCommit> compoundLog = compound(commits);
|
||||
List<GraphCommit<Integer>> graphCommits = compactCommits(compoundLog, myHashMap);
|
||||
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(),
|
||||
@@ -386,24 +393,31 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Collection<List<? extends TimedVcsCommit>> readFullLogFromVcs() throws VcsException {
|
||||
private Collection<List<? extends GraphCommit<Integer>>> readFullLogFromVcs() throws VcsException {
|
||||
final StopWatch sw = StopWatch.start("read full log from VCS");
|
||||
final Collection<List<? extends TimedVcsCommit>> commits = ContainerUtil.newArrayList();
|
||||
final Collection<List<? extends GraphCommit<Integer>>> logs = ContainerUtil.newArrayList();
|
||||
new ProviderIterator() {
|
||||
@Override
|
||||
void each(@NotNull VirtualFile root, @NotNull VcsLogProvider provider) throws VcsException {
|
||||
commits.add(provider.readAllHashes(root, new Consumer<VcsUser>() {
|
||||
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>() {
|
||||
@Override
|
||||
public void consume(TimedVcsCommit commit) {
|
||||
graphCommits.add(compactCommit(commit, myHashMap));
|
||||
}
|
||||
});
|
||||
logs.add(graphCommits);
|
||||
sw.rootCompleted(root);
|
||||
}
|
||||
}.iterate(myProviders);
|
||||
myUserRegistry.flush();
|
||||
sw.report();
|
||||
return commits;
|
||||
return logs;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -93,9 +93,9 @@ public class TestVcsLogProvider implements VcsLogProvider {
|
||||
return ContainerUtil.map(myCommits.subList(0, requirements.getCommitCount()), myCommitToMetadataConvertor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<TimedVcsCommit> readAllHashes(@NotNull VirtualFile root, @NotNull Consumer<VcsUser> userRegistry) throws VcsException {
|
||||
public void readAllHashes(@NotNull VirtualFile root, @NotNull Consumer<VcsUser> userRegistry,
|
||||
@NotNull Consumer<TimedVcsCommit> commitConsumer) throws VcsException {
|
||||
try {
|
||||
myFullLogSemaphore.acquire();
|
||||
}
|
||||
@@ -103,7 +103,9 @@ public class TestVcsLogProvider implements VcsLogProvider {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
assertRoot(root);
|
||||
return myCommits;
|
||||
for (TimedVcsCommit commit : myCommits) {
|
||||
commitConsumer.consume(commit);
|
||||
}
|
||||
}
|
||||
|
||||
private void assertRoot(@NotNull VirtualFile root) {
|
||||
|
||||
@@ -520,9 +520,19 @@ public class GitHistoryUtils {
|
||||
@NotNull VirtualFile root,
|
||||
@NotNull final Consumer<VcsUser> userRegistry,
|
||||
@NotNull List<String> parameters) throws VcsException {
|
||||
List<TimedVcsCommit> collector = ContainerUtil.newArrayList();
|
||||
readCommits(project, root, userRegistry, parameters, new CollectConsumer<TimedVcsCommit>(collector));
|
||||
return collector;
|
||||
}
|
||||
|
||||
public static void readCommits(@NotNull final Project project,
|
||||
@NotNull VirtualFile root,
|
||||
@NotNull final Consumer<VcsUser> userRegistry,
|
||||
@NotNull List<String> parameters,
|
||||
@NotNull final Consumer<TimedVcsCommit> commitConsumer) throws VcsException {
|
||||
final VcsLogObjectsFactory factory = getObjectsFactoryWithDisposeCheck(project);
|
||||
if (factory == null) {
|
||||
return Collections.emptyList();
|
||||
return;
|
||||
}
|
||||
|
||||
final int COMMIT_BUFFER = 1000;
|
||||
@@ -536,8 +546,6 @@ public class GitHistoryUtils {
|
||||
h.addParameters(parameters);
|
||||
h.endOptions();
|
||||
|
||||
final List<TimedVcsCommit> commits = ContainerUtil.newArrayList();
|
||||
|
||||
final StringBuilder record = new StringBuilder();
|
||||
final AtomicInteger records = new AtomicInteger();
|
||||
final Ref<VcsException> ex = new Ref<VcsException>();
|
||||
@@ -560,7 +568,10 @@ public class GitHistoryUtils {
|
||||
afterParseRemainder = line.substring(recordEnd + 1);
|
||||
}
|
||||
if (afterParseRemainder != null && records.incrementAndGet() > COMMIT_BUFFER) { // null means can't parse now
|
||||
commits.addAll(parseCommit(parser, record, userRegistry, factory));
|
||||
List<TimedVcsCommit> commits = parseCommit(parser, record, userRegistry, factory);
|
||||
for (TimedVcsCommit commit : commits) {
|
||||
commitConsumer.consume(commit);
|
||||
}
|
||||
record.setLength(0);
|
||||
record.append(afterParseRemainder);
|
||||
}
|
||||
@@ -573,7 +584,10 @@ public class GitHistoryUtils {
|
||||
@Override
|
||||
public void processTerminated(int exitCode) {
|
||||
try {
|
||||
commits.addAll(parseCommit(parser, record, userRegistry, factory));
|
||||
List<TimedVcsCommit> commits = parseCommit(parser, record, userRegistry, factory);
|
||||
for (TimedVcsCommit commit : commits) {
|
||||
commitConsumer.consume(commit);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
ex.set(new VcsException(e));
|
||||
@@ -589,7 +603,6 @@ public class GitHistoryUtils {
|
||||
if (!ex.isNull()) {
|
||||
throw ex.get();
|
||||
}
|
||||
return commits;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -27,49 +27,34 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.*;
|
||||
|
||||
class GitBekParentFixer {
|
||||
@NotNull
|
||||
private final static String MAGIC_TEXT = "Merge remote";
|
||||
@NotNull
|
||||
private final VcsLogFilterCollection MAGIC_FILTER = createVcsLogFilterCollection();
|
||||
@NotNull private static final String MAGIC_TEXT = "Merge remote";
|
||||
@NotNull private static final VcsLogFilterCollection MAGIC_FILTER = createVcsLogFilterCollection();
|
||||
|
||||
@NotNull
|
||||
private final VirtualFile myRoot;
|
||||
@NotNull
|
||||
private final GitLogProvider myGitLogProvider;
|
||||
@NotNull
|
||||
private final List<TimedVcsCommit> myAllCommits;
|
||||
@NotNull private final Set<Hash> myWrongCommits;
|
||||
|
||||
GitBekParentFixer(@NotNull VirtualFile root, @NotNull GitLogProvider gitLogProvider, @NotNull List<TimedVcsCommit> allCommits) {
|
||||
myRoot = root;
|
||||
myGitLogProvider = gitLogProvider;
|
||||
myAllCommits = allCommits;
|
||||
private GitBekParentFixer(@NotNull Set<Hash> wrongCommits) {
|
||||
myWrongCommits = wrongCommits;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
List<TimedVcsCommit> getCorrectCommits() throws VcsException {
|
||||
if (!BekSorter.isBekEnabled())
|
||||
return myAllCommits;
|
||||
|
||||
final Set<Hash> wrongCommits = getWrongCommits();
|
||||
return new AbstractList<TimedVcsCommit>() {
|
||||
@Override
|
||||
public TimedVcsCommit get(int index) {
|
||||
TimedVcsCommit commit = myAllCommits.get(index);
|
||||
if (!wrongCommits.contains(commit.getId()))
|
||||
return commit;
|
||||
|
||||
return reverseParents(commit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return myAllCommits.size();
|
||||
}
|
||||
};
|
||||
static GitBekParentFixer prepare(@NotNull VirtualFile root, @NotNull GitLogProvider provider) throws VcsException {
|
||||
if (!BekSorter.isBekEnabled()) {
|
||||
return new GitBekParentFixer(Collections.<Hash>emptySet());
|
||||
}
|
||||
return new GitBekParentFixer(getWrongCommits(provider, root));
|
||||
}
|
||||
|
||||
private Set<Hash> getWrongCommits() throws VcsException {
|
||||
List<TimedVcsCommit> commitsMatchingFilter = myGitLogProvider.getCommitsMatchingFilter(myRoot, MAGIC_FILTER, -1);
|
||||
@NotNull
|
||||
TimedVcsCommit fixCommit(@NotNull TimedVcsCommit commit) {
|
||||
if (!myWrongCommits.contains(commit.getId())) {
|
||||
return commit;
|
||||
}
|
||||
return reverseParents(commit);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Set<Hash> getWrongCommits(@NotNull GitLogProvider provider, @NotNull VirtualFile root) throws VcsException {
|
||||
List<TimedVcsCommit> commitsMatchingFilter = provider.getCommitsMatchingFilter(root, MAGIC_FILTER, -1);
|
||||
return ContainerUtil.map2Set(commitsMatchingFilter, new Function<TimedVcsCommit, Hash>() {
|
||||
@Override
|
||||
public Hash fun(TimedVcsCommit timedVcsCommit) {
|
||||
|
||||
@@ -154,18 +154,23 @@ public class GitLogProvider implements VcsLogProvider {
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<TimedVcsCommit> readAllHashes(@NotNull VirtualFile root, @NotNull Consumer<VcsUser> userRegistry) throws VcsException {
|
||||
public void readAllHashes(@NotNull VirtualFile root, @NotNull Consumer<VcsUser> userRegistry,
|
||||
@NotNull final Consumer<TimedVcsCommit> commitConsumer) throws VcsException {
|
||||
if (!isRepositoryReady(root)) {
|
||||
return Collections.emptyList();
|
||||
return;
|
||||
}
|
||||
|
||||
List<String> parameters = new ArrayList<String>(GitHistoryUtils.LOG_ALL);
|
||||
parameters.add("--sparse");
|
||||
|
||||
List<TimedVcsCommit> timedVcsCommits = GitHistoryUtils.readCommits(myProject, root, userRegistry, parameters);
|
||||
return new GitBekParentFixer(root, this, timedVcsCommits).getCorrectCommits();
|
||||
final GitBekParentFixer parentFixer = GitBekParentFixer.prepare(root, this);
|
||||
GitHistoryUtils.readCommits(myProject, root, userRegistry, parameters, new Consumer<TimedVcsCommit>() {
|
||||
@Override
|
||||
public void consume(TimedVcsCommit commit) {
|
||||
commitConsumer.consume(parentFixer.fixCommit(commit));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.CollectConsumer;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
@@ -84,9 +85,10 @@ public class GitLogProviderTest extends GitSingleRepoTest {
|
||||
prepareSomeHistory();
|
||||
createTaggedBranch();
|
||||
List<VcsCommitMetadata> expectedLog = log();
|
||||
@SuppressWarnings("unchecked")
|
||||
List<TimedVcsCommit> actualLog = myLogProvider.readAllHashes(myProjectRoot, Consumer.EMPTY_CONSUMER);
|
||||
assertOrderedEquals(expectedLog, actualLog);
|
||||
List<TimedVcsCommit> collector = ContainerUtil.newArrayList();
|
||||
//noinspection unchecked
|
||||
myLogProvider.readAllHashes(myProjectRoot, Consumer.EMPTY_CONSUMER, new CollectConsumer<TimedVcsCommit>(collector));
|
||||
assertOrderedEquals(expectedLog, collector);
|
||||
}
|
||||
|
||||
public void test_get_current_user() throws Exception {
|
||||
|
||||
@@ -64,10 +64,13 @@ public class HgLogProvider implements VcsLogProvider {
|
||||
return HgHistoryUtil.loadMetadata(myProject, root, requirements.getCommitCount(), Collections.<String>emptyList());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<TimedVcsCommit> readAllHashes(@NotNull VirtualFile root, @NotNull Consumer<VcsUser> userRegistry) throws VcsException {
|
||||
return HgHistoryUtil.readAllHashes(myProject, root, userRegistry, Collections.<String>emptyList());
|
||||
public void readAllHashes(@NotNull VirtualFile root, @NotNull Consumer<VcsUser> userRegistry,
|
||||
@NotNull Consumer<TimedVcsCommit> commitConsumer) throws VcsException {
|
||||
List<TimedVcsCommit> commits = HgHistoryUtil.readAllHashes(myProject, root, userRegistry, Collections.<String>emptyList());
|
||||
for (TimedVcsCommit commit : commits) {
|
||||
commitConsumer.consume(commit);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
Reference in New Issue
Block a user