Merge remote-tracking branch 'origin/master'

This commit is contained in:
Dmitry Trofimov
2014-08-04 17:20:38 +02:00
16 changed files with 184 additions and 137 deletions
@@ -17,8 +17,10 @@ package com.intellij.ide.util;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import com.intellij.util.ObjectUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Field;
@@ -31,6 +33,7 @@ public abstract class PropertiesComponent {
public abstract boolean isValueSet(String name);
@Nullable
public abstract String getValue(@NonNls String name);
public abstract void setValue(@NonNls String name, String value);
@@ -62,7 +65,10 @@ public abstract class PropertiesComponent {
@NotNull
public String getValue(@NonNls String name, @NotNull String defaultValue) {
return isValueSet(name) ? getValue(name) : defaultValue;
if (!isValueSet(name)) {
return defaultValue;
}
return ObjectUtils.notNull(getValue(name), defaultValue);
}
public final int getOrInitInt(@NonNls String name, int defaultValue) {
@@ -1,3 +1,18 @@
/*
* 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.util.ui;
import com.intellij.ide.BrowserUtil;
@@ -48,7 +63,7 @@ public class SwingHelper {
* stacked vertically each on another in a given order.
*
* @param childAlignmentX Component.LEFT_ALIGNMENT, Component.CENTER_ALIGNMENT or Component.RIGHT_ALIGNMENT
* @param children children components
* @param children children components
* @return created panel
*/
@NotNull
@@ -76,7 +91,7 @@ public class SwingHelper {
* stacked each on another in a given order.
*
* @param childAlignmentY Component.TOP_ALIGNMENT, Component.CENTER_ALIGNMENT or Component.BOTTOM_ALIGNMENT
* @param children children components
* @param children children components
* @return created panel
*/
@NotNull
@@ -98,10 +113,11 @@ public class SwingHelper {
for (Component child : children) {
panel.add(child, childAlignment);
if (child instanceof JComponent) {
JComponent jChild = (JComponent) child;
JComponent jChild = (JComponent)child;
if (verticalOrientation) {
jChild.setAlignmentX(childAlignment);
} else {
}
else {
jChild.setAlignmentY(childAlignment);
}
}
@@ -291,7 +307,7 @@ public class SwingHelper {
Object prototypeDisplayValue = comboBox.getPrototypeDisplayValue();
String prototypeDisplayValueStr = null;
if (prototypeDisplayValue instanceof String) {
prototypeDisplayValueStr = (String) prototypeDisplayValue;
prototypeDisplayValueStr = (String)prototypeDisplayValue;
}
else if (prototypeDisplayValue != null) {
return;
@@ -424,6 +440,24 @@ public class SwingHelper {
editorPane.setText(html);
}
public static TextFieldWithHistoryWithBrowseButton createTextFieldWithHistoryWithBrowseButton(@Nullable Project project,
@NotNull String browseDialogTitle,
@NotNull FileChooserDescriptor fileChooserDescriptor,
@NotNull NotNullProducer<List<String>> historyProvider) {
TextFieldWithHistoryWithBrowseButton textFieldWithHistoryWithBrowseButton = new TextFieldWithHistoryWithBrowseButton();
final TextFieldWithHistory textFieldWithHistory = textFieldWithHistoryWithBrowseButton.getChildComponent();
textFieldWithHistory.setHistorySize(-1);
textFieldWithHistory.setMinimumAndPreferredWidth(0);
addHistoryOnExpansion(textFieldWithHistory, historyProvider);
installFileCompletionAndBrowseDialog(
project,
textFieldWithHistoryWithBrowseButton,
browseDialogTitle, fileChooserDescriptor
);
return textFieldWithHistoryWithBrowseButton;
}
private static class CopyLinkAction extends AnAction {
private final String myUrl;
@@ -20,7 +20,7 @@ import com.intellij.vcs.log.graph.GraphCommit;
import java.util.List;
/**
* A {@link GraphCommit} with information about date & time when this commit was made.
* A typified {@link GraphCommit}.
* <p/>
* An instance of this object can be obtained via
* {@link VcsLogObjectsFactory#createTimedCommit(Hash, List, long) VcsLogObjectsFactory#createTimedCommit}.
@@ -31,12 +31,4 @@ import java.util.List;
*/
public interface TimedVcsCommit extends GraphCommit<Hash> {
/**
* <p>Returns the timestamp indicating the date & time when this commit was made.</p>
* <p>This time is displayed in the table by default;
* is used for joining commits from different repositories;
* is used for ordering commits in a single repository (keeping the preference of the topological ordering of course).</p>
*/
long getTimestamp();
}
@@ -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.
@@ -21,20 +21,9 @@ import java.util.List;
*/
public interface VcsShortCommitDetails extends TimedVcsCommit {
@Override
@NotNull
Hash getId();
@NotNull
VirtualFile getRoot();
@Override
@NotNull
List<Hash> getParents();
@Override
long getTimestamp();
@NotNull
String getSubject();
@@ -29,6 +29,12 @@ public interface GraphCommit<CommitId> {
@NotNull
List<CommitId> getParents();
/**
* <p>Returns the timestamp indicating the date & time when this commit was made.</p>
* <p>This time is displayed in the table by default;
* it is used for joining commits from different repositories;
* it is used for ordering commits in a single repository (keeping the preference of the topological ordering of course).</p>
*/
long getTimestamp();
}
@@ -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) {
@@ -15,7 +15,6 @@
*/
package com.intellij.xdebugger.impl.actions.handlers;
import com.intellij.xdebugger.XDebuggerUtil;
import com.intellij.xdebugger.impl.actions.XDebuggerSuspendedActionHandler;
import com.intellij.xdebugger.impl.XDebuggerUtilImpl;
import com.intellij.xdebugger.XDebugSession;
@@ -34,9 +33,7 @@ public class XDebuggerRunToCursorActionHandler extends XDebuggerSuspendedActionH
}
protected boolean isEnabled(final @NotNull XDebugSession session, final DataContext dataContext) {
if (!super.isEnabled(session, dataContext)) return false;
XSourcePosition position = XDebuggerUtilImpl.getCaretPosition(session.getProject(), dataContext);
return position != null && XDebuggerUtil.getInstance().canPutBreakpointAt(session.getProject(), position.getFile(), position.getLine());
return super.isEnabled(session, dataContext) && XDebuggerUtilImpl.getCaretPosition(session.getProject(), dataContext) != null;
}
protected void perform(@NotNull final XDebugSession session, final DataContext dataContext) {
@@ -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
+1 -2
View File
@@ -331,8 +331,7 @@ private layoutWin(Map args, String target) {
}
winScripts(target, ch, "pycharm.bat", args)
winVMOptions(target, null, "pycharm.exe")
winVMOptions(target, null, "pycharm.exe", "pycharm64.exe")
ant.copy(file: "$home/python/help/pycharmhelp.jar", todir: "$target/help", failonerror: false)
}