summaryrefslogtreecommitdiff
path: root/platform/vcs-log/impl/src/com
diff options
context:
space:
mode:
Diffstat (limited to 'platform/vcs-log/impl/src/com')
-rw-r--r--platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogFilterer.java22
-rw-r--r--platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogRefresherImpl.java67
-rw-r--r--platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogFilterCollectionImpl.java9
-rw-r--r--platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogHashFilterImpl.java36
-rw-r--r--platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogSettingsImpl.java5
-rw-r--r--platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsLogClassicFilterUi.java41
6 files changed, 157 insertions, 23 deletions
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogFilterer.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogFilterer.java
index 5a1766d9cb81..f0bf75c08dcf 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogFilterer.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogFilterer.java
@@ -48,11 +48,33 @@ public class VcsLogFilterer {
@NotNull
public AbstractVcsLogTableModel applyFiltersAndUpdateUi(@NotNull DataPack dataPack, @NotNull VcsLogFilterCollection filters) {
resetFilters(dataPack);
+ VcsLogHashFilter hashFilter = filters.getHashFilter();
+ if (hashFilter != null && !hashFilter.getHashes().isEmpty()) { // hashes should be shown, no matter if they match other filters or not
+ return applyHashFilter(dataPack, hashFilter.getHashes());
+ }
List<VcsLogDetailsFilter> detailsFilters = filters.getDetailsFilters();
applyGraphFilters(dataPack, filters.getBranchFilter());
return applyDetailsFilter(dataPack, detailsFilters);
}
+ private GraphTableModel applyHashFilter(@NotNull DataPack dataPack, @NotNull Collection<String> hashes) {
+ final List<Integer> indices = ContainerUtil.mapNotNull(hashes, new Function<String, Integer>() {
+ @Override
+ public Integer fun(String partOfHash) {
+ Hash hash = myLogDataHolder.findHashByString(partOfHash);
+ return hash != null ? myLogDataHolder.getCommitIndex(hash) : null;
+ }
+ });
+ dataPack.getGraphFacade().setVisibleBranches(null);
+ dataPack.getGraphFacade().setFilter(new Condition<Integer>() {
+ @Override
+ public boolean value(Integer integer) {
+ return indices.contains(integer);
+ }
+ });
+ return new GraphTableModel(dataPack, myLogDataHolder, myUI, LoadMoreStage.ALL_REQUESTED);
+ }
+
private static void resetFilters(@NotNull DataPack dataPack) {
GraphFacade facade = dataPack.getGraphFacade();
facade.setVisibleBranches(null);
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 12996f91c116..c7ab5e324b3d 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
@@ -15,12 +15,14 @@
*/
package com.intellij.vcs.log.data;
+import com.intellij.openapi.diagnostic.Attachment;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.progress.impl.ProgressManagerImpl;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Consumer;
@@ -272,22 +274,23 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
Map<VirtualFile, Collection<VcsRef>> currentRefs = myCurrentDataPack.getRefsModel().getAllRefsByRoot();
try {
if (permanentGraph != null) {
- loadLogAndRefs(roots, currentRefs, myRecentCommitCount);
- List<? extends GraphCommit<Integer>> compoundLog = compound(ContainerUtil.map(myLoadedInfos.values(),
- new Function<LogAndRefs, List<? extends GraphCommit<Integer>>>() {
- @Override
- public List<? extends GraphCommit<Integer>> fun(
- LogAndRefs refs) {
- return refs.log;
- }
- }));
- Map<VirtualFile, Collection<VcsRef>> allNewRefs = getAllNewRefs(myLoadedInfos, currentRefs);
- 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);
+ 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<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);
+ }
}
- // couldn't join => need to reload everything; this shouldn't happen often, the error is logged in join().
+ // 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)));
}
Pair<PermanentGraph<Integer>, Map<VirtualFile, Collection<VcsRef>>> fullLogAndRefs = loadFullLog();
@@ -302,6 +305,38 @@ 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) {
@@ -374,7 +409,7 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
return commits;
}
catch (VcsLogRefreshNotEnoughDataException e) {
- LOG.error(e); // collecting information : how often this situation happens, do we need to try to load more or can safely reload all
+ LOG.info(e);
}
catch (IllegalStateException e) {
LOG.error(e);
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogFilterCollectionImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogFilterCollectionImpl.java
index 285e3ce91079..3fbb7cb7b82f 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogFilterCollectionImpl.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogFilterCollectionImpl.java
@@ -27,17 +27,20 @@ public class VcsLogFilterCollectionImpl implements VcsLogFilterCollection {
@Nullable private final VcsLogBranchFilter myBranchFilter;
@Nullable private final VcsLogUserFilter myUserFilter;
+ @Nullable private final VcsLogHashFilter myHashFilter;
@Nullable private final VcsLogDateFilter myDateFilter;
@Nullable private final VcsLogTextFilter myTextFilter;
@Nullable private final VcsLogStructureFilter myStructureFilter;
public VcsLogFilterCollectionImpl(@Nullable VcsLogBranchFilter branchFilter,
@Nullable VcsLogUserFilter userFilter,
+ @Nullable VcsLogHashFilter hashFilter,
@Nullable VcsLogDateFilter dateFilter,
@Nullable VcsLogTextFilter textFilter,
@Nullable VcsLogStructureFilter structureFilter) {
myBranchFilter = branchFilter;
myUserFilter = userFilter;
+ myHashFilter = hashFilter;
myDateFilter = dateFilter;
myTextFilter = textFilter;
myStructureFilter = structureFilter;
@@ -49,6 +52,12 @@ public class VcsLogFilterCollectionImpl implements VcsLogFilterCollection {
return myBranchFilter;
}
+ @Override
+ @Nullable
+ public VcsLogHashFilter getHashFilter() {
+ return myHashFilter;
+ }
+
@Nullable
@Override
public VcsLogUserFilter getUserFilter() {
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogHashFilterImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogHashFilterImpl.java
new file mode 100644
index 000000000000..ff747f4f37d4
--- /dev/null
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogHashFilterImpl.java
@@ -0,0 +1,36 @@
+/*
+ * 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.VcsLogHashFilter;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+
+public class VcsLogHashFilterImpl implements VcsLogHashFilter {
+
+ @NotNull private final Collection<String> myHashes;
+
+ public VcsLogHashFilterImpl(@NotNull Collection<String> hashes) {
+ myHashes = hashes;
+ }
+
+ @NotNull
+ @Override
+ public Collection<String> getHashes() {
+ return myHashes;
+ }
+}
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogSettingsImpl.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogSettingsImpl.java
index 88b2b449ac69..016f08451a95 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogSettingsImpl.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsLogSettingsImpl.java
@@ -45,9 +45,4 @@ public class VcsLogSettingsImpl implements VcsLogSettings, PersistentStateCompon
public void setShowBranchesPanel(boolean show) {
myState.SHOW_BRANCHES_PANEL = show;
}
-
- public void setRecentCommitsBlockSize(int commitCount) {
- myState.RECENT_COMMITS_COUNT = commitCount;
- }
-
}
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsLogClassicFilterUi.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsLogClassicFilterUi.java
index d18c99c4e24c..9a44f320f040 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsLogClassicFilterUi.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsLogClassicFilterUi.java
@@ -20,15 +20,20 @@ import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.actionSystem.ex.CustomComponentAction;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.DumbAwareAction;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.SearchTextField;
import com.intellij.ui.SearchTextFieldWithStoredHistory;
+import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.UIUtil;
import com.intellij.vcs.log.*;
import com.intellij.vcs.log.data.DataPack;
import com.intellij.vcs.log.data.VcsLogDataHolder;
import com.intellij.vcs.log.data.VcsLogUiProperties;
import com.intellij.vcs.log.impl.VcsLogFilterCollectionImpl;
+import com.intellij.vcs.log.impl.VcsLogHashFilterImpl;
import com.intellij.vcs.log.ui.VcsLogUiImpl;
import org.jetbrains.annotations.NotNull;
@@ -43,6 +48,9 @@ import java.util.List;
*/
public class VcsLogClassicFilterUi implements VcsLogFilterUi {
+ private static final Logger LOG = Logger.getInstance(VcsLogClassicFilterUi.class);
+ private static final String HASH_PATTERN = "[a-fA-F0-9]{7,}";
+
@NotNull private final SearchTextField myTextFilter;
@NotNull private final VcsLogUiImpl myUi;
@NotNull private final DefaultActionGroup myActionGroup;
@@ -104,9 +112,38 @@ public class VcsLogClassicFilterUi implements VcsLogFilterUi {
@NotNull
@Override
public VcsLogFilterCollection getFilters() {
- VcsLogTextFilter textFilter = !myTextFilter.getText().isEmpty() ? new VcsLogTextFilterImpl(myTextFilter.getText().trim()) : null;
+ Pair<VcsLogTextFilter, VcsLogHashFilter> filtersFromText = getFiltersFromTextArea(myTextFilter.getText().trim());
return new VcsLogFilterCollectionImpl(myBranchFilterComponent.getFilter(), myUserFilterComponent.getFilter(),
- myDateFilterComponent.getFilter(), textFilter, myStructureFilterComponent.getFilter());
+ filtersFromText.second, myDateFilterComponent.getFilter(),
+ filtersFromText.first, myStructureFilterComponent.getFilter());
+ }
+
+ @NotNull
+ private static Pair<VcsLogTextFilter, VcsLogHashFilter> getFiltersFromTextArea(@NotNull String text) {
+ if (text.isEmpty()) {
+ return Pair.empty();
+ }
+ List<String> hashes = ContainerUtil.newArrayList();
+ for (String word : StringUtil.split(text, " ")) {
+ if (!StringUtil.isEmptyOrSpaces(word) && word.matches(HASH_PATTERN)) {
+ hashes.add(word);
+ }
+ else {
+ break;
+ }
+ }
+
+ VcsLogTextFilter textFilter;
+ VcsLogHashFilterImpl hashFilter;
+ if (!hashes.isEmpty()) { // text is ignored if there are hashes in the text
+ textFilter = null;
+ hashFilter = new VcsLogHashFilterImpl(hashes);
+ }
+ else {
+ textFilter = new VcsLogTextFilterImpl(text);
+ hashFilter = null;
+ }
+ return Pair.<VcsLogTextFilter, VcsLogHashFilter>create(textFilter, hashFilter);
}
@Override