From 16e0e2eb7421c3b2f39b9c67ca065e3cec25bcf7 Mon Sep 17 00:00:00 2001 From: "Ilia.Shulgin" Date: Thu, 13 Jun 2024 12:14:55 +0200 Subject: [PATCH] [git] Ignore case when listing git branches IJPL-86830 IJPL-150396 IJPL-112392 GitOrigin-RevId: 312a60bbbd45da06610012f1b4710c76d8c65fdd --- platform/util/base/api-dump.txt | 1 + .../intellij/openapi/util/text/NaturalComparator.java | 8 ++++++++ .../vcs/log/ui/filter/BranchPopupBuilder.java | 4 +++- plugins/git4idea/src/git4idea/GitLocalBranch.java | 4 +--- plugins/git4idea/src/git4idea/GitReference.java | 11 +++++++++-- .../src/git4idea/GitStandardRemoteBranch.java | 4 +--- plugins/git4idea/src/git4idea/GitTag.java | 4 +--- plugins/git4idea/src/git4idea/log/GitRefManager.kt | 3 ++- .../ui/branch/dashboard/BranchTreeNodeComparator.kt | 2 +- .../ui/branch/tree/GitBranchesTreeModelUtil.kt | 2 +- 10 files changed, 28 insertions(+), 15 deletions(-) diff --git a/platform/util/base/api-dump.txt b/platform/util/base/api-dump.txt index c0636611b255..f04e3160d66e 100644 --- a/platform/util/base/api-dump.txt +++ b/platform/util/base/api-dump.txt @@ -96,6 +96,7 @@ f:com.intellij.openapi.util.text.NaturalComparator - sf:INSTANCE:java.util.Comparator - ():V - compare(java.lang.String,java.lang.String):I +- s:naturalCompare(java.lang.String,java.lang.String,Z,Z):I f:com.intellij.openapi.util.text.Strings - sf:EMPTY_CHAR_SEQUENCE:java.lang.CharSequence - ():V diff --git a/platform/util/base/src/com/intellij/openapi/util/text/NaturalComparator.java b/platform/util/base/src/com/intellij/openapi/util/text/NaturalComparator.java index 854973fdb831..3b0ca268f3dd 100644 --- a/platform/util/base/src/com/intellij/openapi/util/text/NaturalComparator.java +++ b/platform/util/base/src/com/intellij/openapi/util/text/NaturalComparator.java @@ -25,6 +25,14 @@ public final class NaturalComparator implements Comparator { return naturalCompare(s1, s2, s1.length(), s2.length(), true, false); } + @Contract(pure = true) + public static int naturalCompare(@NotNull String s1, + @NotNull String s2, + boolean ignoreCase, + boolean likeFileNames) { + return naturalCompare(s1, s2, s1.length(), s2.length(), ignoreCase, likeFileNames); + } + @Contract(pure = true) @ApiStatus.Internal public static int naturalCompare(@NotNull String s1, diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/BranchPopupBuilder.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/BranchPopupBuilder.java index 862d91875a44..b4e362f9dcca 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/BranchPopupBuilder.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/BranchPopupBuilder.java @@ -7,6 +7,7 @@ import com.intellij.openapi.actionSystem.DefaultActionGroup; import com.intellij.openapi.actionSystem.Separator; import com.intellij.openapi.util.NlsActions; import com.intellij.openapi.util.NlsContexts; +import com.intellij.openapi.util.text.NaturalComparator; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.containers.ContainerUtil; import com.intellij.vcs.log.RefGroup; @@ -136,7 +137,8 @@ public abstract class BranchPopupBuilder { else { TreeMap>> groups = refGroup.isExpanded() ? actions.expandedGroups : actions.collapsedGroups; - TreeMap> groupActions = groups.computeIfAbsent(refGroup.getName(), key -> new TreeMap<>()); + TreeMap> groupActions = + groups.computeIfAbsent(refGroup.getName(), key -> new TreeMap<>(NaturalComparator.INSTANCE)); for (VcsRef ref : refGroup.getRefs()) { if (isFavorite(pack, ref)) { append(actions.favoriteGroups, ref.getName(), ref); diff --git a/plugins/git4idea/src/git4idea/GitLocalBranch.java b/plugins/git4idea/src/git4idea/GitLocalBranch.java index 435308ef5049..18be08a1d55d 100644 --- a/plugins/git4idea/src/git4idea/GitLocalBranch.java +++ b/plugins/git4idea/src/git4idea/GitLocalBranch.java @@ -1,8 +1,6 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package git4idea; -import com.intellij.openapi.util.SystemInfo; -import com.intellij.openapi.util.text.StringUtil; import git4idea.branch.GitBranchUtil; import git4idea.repo.GitBranchTrackInfo; import git4idea.repo.GitRepository; @@ -32,7 +30,7 @@ public final class GitLocalBranch extends GitBranch { public int compareTo(GitReference o) { if (o instanceof GitLocalBranch) { // optimization: do not build getFullName - return StringUtil.compare(myName, o.myName, SystemInfo.isFileSystemCaseSensitive); + return REFS_NAMES_COMPARATOR.compare(myName, o.myName); } return super.compareTo(o); } diff --git a/plugins/git4idea/src/git4idea/GitReference.java b/plugins/git4idea/src/git4idea/GitReference.java index 819649a71f8d..7e4da2130e1c 100644 --- a/plugins/git4idea/src/git4idea/GitReference.java +++ b/plugins/git4idea/src/git4idea/GitReference.java @@ -4,10 +4,12 @@ package git4idea; import com.intellij.openapi.util.NlsSafe; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.SystemInfoRt; -import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.util.text.NaturalComparator; import com.intellij.util.containers.HashingStrategy; import org.jetbrains.annotations.NotNull; +import java.util.Comparator; + /** * The base class for named git references, like branches and tags. */ @@ -16,6 +18,11 @@ public abstract class GitReference implements Comparable { public static final HashingStrategy BRANCH_NAME_HASHING_STRATEGY = SystemInfoRt.isFileSystemCaseSensitive ? HashingStrategy.canonical() : HashingStrategy.caseInsensitive(); + public static final Comparator<@NotNull String> REFS_NAMES_COMPARATOR = (name1, name2) -> { + boolean ignoreCase = !SystemInfo.isFileSystemCaseSensitive; + return NaturalComparator.naturalCompare(name1, name2, ignoreCase, false); + }; + protected final @NotNull String myName; public GitReference(@NotNull String name) { @@ -56,6 +63,6 @@ public abstract class GitReference implements Comparable { @Override public int compareTo(GitReference o) { // NB: update overridden comparators on modifications - return o == null ? 1 : StringUtil.compare(getFullName(), o.getFullName(), SystemInfo.isFileSystemCaseSensitive); + return o == null ? 1 : REFS_NAMES_COMPARATOR.compare(getFullName(), o.getFullName()); } } diff --git a/plugins/git4idea/src/git4idea/GitStandardRemoteBranch.java b/plugins/git4idea/src/git4idea/GitStandardRemoteBranch.java index 17aa70370cb0..96fb5d01f406 100644 --- a/plugins/git4idea/src/git4idea/GitStandardRemoteBranch.java +++ b/plugins/git4idea/src/git4idea/GitStandardRemoteBranch.java @@ -1,8 +1,6 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package git4idea; -import com.intellij.openapi.util.SystemInfo; -import com.intellij.openapi.util.text.StringUtil; import git4idea.branch.GitBranchUtil; import git4idea.repo.GitRemote; import org.jetbrains.annotations.NotNull; @@ -63,7 +61,7 @@ public final class GitStandardRemoteBranch extends GitRemoteBranch { public int compareTo(GitReference o) { if (o instanceof GitStandardRemoteBranch) { // optimization: do not build getFullName - return StringUtil.compare(myName, o.myName, SystemInfo.isFileSystemCaseSensitive); + return REFS_NAMES_COMPARATOR.compare(myName, o.myName); } return super.compareTo(o); } diff --git a/plugins/git4idea/src/git4idea/GitTag.java b/plugins/git4idea/src/git4idea/GitTag.java index d83351c4e736..1307673363ac 100644 --- a/plugins/git4idea/src/git4idea/GitTag.java +++ b/plugins/git4idea/src/git4idea/GitTag.java @@ -1,8 +1,6 @@ // Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package git4idea; -import com.intellij.openapi.util.SystemInfo; -import com.intellij.openapi.util.text.StringUtil; import git4idea.branch.GitBranchUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -23,7 +21,7 @@ public final class GitTag extends GitReference { public int compareTo(GitReference o) { if (o instanceof GitTag) { // optimization: do not build getFullName - return StringUtil.compare(myName, o.myName, SystemInfo.isFileSystemCaseSensitive); + return REFS_NAMES_COMPARATOR.compare(myName, o.myName); } return super.compareTo(o); } diff --git a/plugins/git4idea/src/git4idea/log/GitRefManager.kt b/plugins/git4idea/src/git4idea/log/GitRefManager.kt index 6b52c017982d..abf9a058d327 100644 --- a/plugins/git4idea/src/git4idea/log/GitRefManager.kt +++ b/plugins/git4idea/src/git4idea/log/GitRefManager.kt @@ -17,6 +17,7 @@ import com.intellij.vcs.log.impl.SimpleRefType import com.intellij.vcs.log.impl.SingletonRefGroup import com.intellij.vcs.log.util.VcsLogUtil import git4idea.GitBranch +import git4idea.GitReference import git4idea.GitTag import git4idea.branch.GitBranchType import git4idea.i18n.GitBundle @@ -234,7 +235,7 @@ class GitRefManager(project: Project, private val repositoryManager: RepositoryM if (power1 != power2) { return power1 - power2 } - val namesComparison = ref1.name.compareTo(ref2.name) + val namesComparison = GitReference.REFS_NAMES_COMPARATOR.compare(ref1.name, ref2.name) return if (namesComparison != 0) { namesComparison } diff --git a/plugins/git4idea/src/git4idea/ui/branch/dashboard/BranchTreeNodeComparator.kt b/plugins/git4idea/src/git4idea/ui/branch/dashboard/BranchTreeNodeComparator.kt index e4b63452c8bc..4f770b35fe14 100644 --- a/plugins/git4idea/src/git4idea/ui/branch/dashboard/BranchTreeNodeComparator.kt +++ b/plugins/git4idea/src/git4idea/ui/branch/dashboard/BranchTreeNodeComparator.kt @@ -11,7 +11,7 @@ internal object BranchTreeNodeComparator : Comparator { val displayText1 = d1.getDisplayText() val displayText2 = d2.getDisplayText() if (displayText1 != null && displayText2 != null) { - return displayText1.compareTo(displayText2) + return displayText1.compareTo(displayText2, ignoreCase = true) } if (displayText1 != null) return -1 if (displayText2 != null) return 1 diff --git a/plugins/git4idea/src/git4idea/ui/branch/tree/GitBranchesTreeModelUtil.kt b/plugins/git4idea/src/git4idea/ui/branch/tree/GitBranchesTreeModelUtil.kt index ae08b55364c6..f9e7d5d7b9ac 100644 --- a/plugins/git4idea/src/git4idea/ui/branch/tree/GitBranchesTreeModelUtil.kt +++ b/plugins/git4idea/src/git4idea/ui/branch/tree/GitBranchesTreeModelUtil.kt @@ -61,7 +61,7 @@ internal fun getRefComparator( it.isNotFavorite(favoriteBranches, repositories) } then compareBy { !(isPrefixGrouping() && it.name.contains('/')) - } then compareBy { it.name } + } then compareBy(GitReference.REFS_NAMES_COMPARATOR) { it.name } } internal fun getSubTreeComparator(favoriteBranches: Map>,