From 3bd310b1d3e52f722ba7dab344aa9308861813b9 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Wed, 24 Dec 2014 18:27:10 +0300 Subject: [PATCH] [git] IDEA-115780 Let branch and tag with same name in the log The purpose of the special refs hashing strategy is to make sure we don't receive the same reference pointing to different hashes. However, type is still important, since we don't store "refs/tags" prefixes in the name. --- .../src/git4idea/history/GitHistoryUtils.java | 9 ++------ .../src/git4idea/log/GitLogProvider.java | 8 +++---- .../git4idea/log/GitLogProviderTest.java | 23 +++++++++++++++++++ 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java b/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java index 9d1e27395ca0..c9824aeec26f 100644 --- a/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java +++ b/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java @@ -40,12 +40,7 @@ import com.intellij.vcs.log.*; import com.intellij.vcs.log.impl.HashImpl; import com.intellij.vcs.log.impl.LogDataImpl; import com.intellij.vcs.log.util.StopWatch; -import git4idea.GitBranch; -import git4idea.GitCommit; -import git4idea.GitFileRevision; -import git4idea.GitRevisionNumber; -import git4idea.GitUtil; -import git4idea.GitVcs; +import git4idea.*; import git4idea.branch.GitBranchUtil; import git4idea.commands.*; import git4idea.config.GitVersionSpecialty; @@ -740,7 +735,7 @@ public class GitHistoryUtils { if (factory == null) { return LogDataImpl.empty(); } - final Set refs = new OpenTHashSet(GitLogProvider.REF_ONLY_NAME_STRATEGY); + final Set refs = new OpenTHashSet(GitLogProvider.DONT_CONSIDER_SHA); final List commits = loadDetails(project, root, withRefs, false, new NullableFunction() { @Nullable diff --git a/plugins/git4idea/src/git4idea/log/GitLogProvider.java b/plugins/git4idea/src/git4idea/log/GitLogProvider.java index 59e3babe372d..3c4e0a3034c7 100644 --- a/plugins/git4idea/src/git4idea/log/GitLogProvider.java +++ b/plugins/git4idea/src/git4idea/log/GitLogProvider.java @@ -55,15 +55,15 @@ public class GitLogProvider implements VcsLogProvider { return ref.getType() == GitRefManager.TAG ? ref.getName() : null; } }; - public static final TObjectHashingStrategy REF_ONLY_NAME_STRATEGY = new TObjectHashingStrategy() { + public static final TObjectHashingStrategy DONT_CONSIDER_SHA = new TObjectHashingStrategy() { @Override public int computeHashCode(@NotNull VcsRef ref) { - return ref.getName().hashCode(); + return 31 * ref.getName().hashCode() + ref.getType().hashCode(); } @Override public boolean equals(@NotNull VcsRef ref1, @NotNull VcsRef ref2) { - return ref1.getName().equals(ref2.getName()); + return ref1.getName().equals(ref2.getName()) && ref1.getType().equals(ref2.getType()); } }; @@ -104,7 +104,7 @@ public class GitLogProvider implements VcsLogProvider { DetailedLogData data = GitHistoryUtils.loadMetadata(myProject, root, true, params); Set safeRefs = data.getRefs(); - Set allRefs = new OpenTHashSet(safeRefs, REF_ONLY_NAME_STRATEGY); + Set allRefs = new OpenTHashSet(safeRefs, DONT_CONSIDER_SHA); Set branches = readBranches(repository); addNewElements(allRefs, branches); diff --git a/plugins/git4idea/tests/git4idea/log/GitLogProviderTest.java b/plugins/git4idea/tests/git4idea/log/GitLogProviderTest.java index f4afb51a8e21..2b086f459cf1 100644 --- a/plugins/git4idea/tests/git4idea/log/GitLogProviderTest.java +++ b/plugins/git4idea/tests/git4idea/log/GitLogProviderTest.java @@ -136,6 +136,29 @@ public class GitLogProviderTest extends GitSingleRepoTest { })); } + public void test_support_equally_named_branch_and_tag() throws Exception { + prepareSomeHistory(); + git("branch build"); + git("tag build"); + + VcsLogProvider.DetailedLogData data = myLogProvider.readFirstBlock(myProjectRoot, + new RequirementsImpl(1000, true, Collections.emptySet())); + List expectedLog = log(); + assertOrderedEquals(data.getCommits(), expectedLog); + assertTrue(ContainerUtil.exists(data.getRefs(), new Condition() { + @Override + public boolean value(VcsRef ref) { + return ref.getName().equals("build") && ref.getType() == GitRefManager.LOCAL_BRANCH; + } + })); + assertTrue(ContainerUtil.exists(data.getRefs(), new Condition() { + @Override + public boolean value(VcsRef ref) { + return ref.getName().equals("build") && ref.getType() == GitRefManager.TAG; + } + })); + } + private static void prepareSomeHistory() { tac("a.txt"); git("tag ATAG");