From 02e5afb17afe971066b3d00cdfec57dd363f190b Mon Sep 17 00:00:00 2001 From: Erokhin Stanislav Date: Mon, 19 May 2014 20:53:26 +0400 Subject: [PATCH] [log] Add GitBekParentFixer for GitLogProvider. --- .../src/git4idea/log/GitBekParentFixer.java | 156 ++++++++++++++++++ .../src/git4idea/log/GitLogProvider.java | 4 +- 2 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 plugins/git4idea/src/git4idea/log/GitBekParentFixer.java diff --git a/plugins/git4idea/src/git4idea/log/GitBekParentFixer.java b/plugins/git4idea/src/git4idea/log/GitBekParentFixer.java new file mode 100644 index 000000000000..e518b764ddd2 --- /dev/null +++ b/plugins/git4idea/src/git4idea/log/GitBekParentFixer.java @@ -0,0 +1,156 @@ +/* + * 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 git4idea.log; + +import com.intellij.openapi.vcs.VcsException; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.vcs.log.*; +import org.jetbrains.annotations.NotNull; +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 final VirtualFile myRoot; + @NotNull + private final GitLogProvider myGitLogProvider; + @NotNull + private final List myAllCommits; + + GitBekParentFixer(@NotNull VirtualFile root, @NotNull GitLogProvider gitLogProvider, @NotNull List allCommits) { + myRoot = root; + myGitLogProvider = gitLogProvider; + myAllCommits = allCommits; + } + + @NotNull + List getCorrectCommits() throws VcsException { + final Set wrongCommits = getWrongCommits(); + return new AbstractList() { + @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(); + } + }; + } + + private Set getWrongCommits() throws VcsException { + List commitsMatchingFilter = myGitLogProvider.getCommitsMatchingFilter(myRoot, MAGIC_FILTER, -1); + return ContainerUtil.map2Set(commitsMatchingFilter, new Function() { + @Override + public Hash fun(TimedVcsCommit timedVcsCommit) { + return timedVcsCommit.getId(); + } + }); + } + + @NotNull + private static TimedVcsCommit reverseParents(@NotNull final TimedVcsCommit commit) { + return new TimedVcsCommit() { + @Override + public long getTimestamp() { + return commit.getTimestamp(); + } + + @NotNull + @Override + public Hash getId() { + return commit.getId(); + } + + @NotNull + @Override + public List getParents() { + return ContainerUtil.reverse(commit.getParents()); + } + }; + } + + private static VcsLogFilterCollection createVcsLogFilterCollection() { + final VcsLogTextFilter textFilter = new VcsLogTextFilter() { + @NotNull + @Override + public String getText() { + return MAGIC_TEXT; + } + + @Override + public boolean matches(@NotNull VcsCommitMetadata details) { + return details.getFullMessage().contains(MAGIC_TEXT); + } + }; + + return new VcsLogFilterCollection() { + @Nullable + @Override + public VcsLogBranchFilter getBranchFilter() { + return null; + } + + @Nullable + @Override + public VcsLogUserFilter getUserFilter() { + return null; + } + + @Nullable + @Override + public VcsLogDateFilter getDateFilter() { + return null; + } + + @Nullable + @Override + public VcsLogTextFilter getTextFilter() { + return textFilter; + } + + @Nullable + @Override + public VcsLogStructureFilter getStructureFilter() { + return null; + } + + @Override + public boolean isEmpty() { + return false; + } + + @NotNull + @Override + public List getDetailsFilters() { + return Collections.singletonList(textFilter); + } + }; + } +} diff --git a/plugins/git4idea/src/git4idea/log/GitLogProvider.java b/plugins/git4idea/src/git4idea/log/GitLogProvider.java index fdf6cf12687a..ecc4709be5d3 100644 --- a/plugins/git4idea/src/git4idea/log/GitLogProvider.java +++ b/plugins/git4idea/src/git4idea/log/GitLogProvider.java @@ -163,7 +163,9 @@ public class GitLogProvider implements VcsLogProvider { List parameters = new ArrayList(GitHistoryUtils.LOG_ALL); parameters.add("--sparse"); - return GitHistoryUtils.readCommits(myProject, root, userRegistry, parameters); + + List timedVcsCommits = GitHistoryUtils.readCommits(myProject, root, userRegistry, parameters); + return new GitBekParentFixer(root, this, timedVcsCommits).getCorrectCommits(); } @NotNull