From f57c1c02efef6ea702ce200070f93af44abe5a4c Mon Sep 17 00:00:00 2001 From: Ilya Zinoviev Date: Sun, 17 Jul 2016 11:28:40 +0300 Subject: [PATCH] IDEA-157915 resolve Git symbolic-ref in HEAD --- .../src/git4idea/repo/GitRepositoryFiles.java | 5 ++++ .../git4idea/repo/GitRepositoryReader.java | 23 ++++++++++++++++--- .../repo/symbolic-refs/current-branch.txt | 2 +- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/plugins/git4idea/src/git4idea/repo/GitRepositoryFiles.java b/plugins/git4idea/src/git4idea/repo/GitRepositoryFiles.java index 017d47c2889c..f77525642ffc 100644 --- a/plugins/git4idea/src/git4idea/repo/GitRepositoryFiles.java +++ b/plugins/git4idea/src/git4idea/repo/GitRepositoryFiles.java @@ -316,4 +316,9 @@ public class GitRepositoryFiles { Collection getRootDirs() { return ContainerUtil.newHashSet(myMainDir, myWorktreeDir); } + + @NotNull + File getBranchFile(@NotNull String fullBranchName) { + return file(myMainDir.getPath() + slash(fullBranchName)); + } } diff --git a/plugins/git4idea/src/git4idea/repo/GitRepositoryReader.java b/plugins/git4idea/src/git4idea/repo/GitRepositoryReader.java index d646eb7609ea..236f71e4857c 100644 --- a/plugins/git4idea/src/git4idea/repo/GitRepositoryReader.java +++ b/plugins/git4idea/src/git4idea/repo/GitRepositoryReader.java @@ -23,6 +23,7 @@ import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.LineTokenizer; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.CharsetToolkit; import com.intellij.util.Function; import com.intellij.util.Processor; @@ -320,9 +321,14 @@ class GitRepositoryReader { @NotNull private HeadInfo readHead() { + return readHeadInternal(myHeadFile, new ArrayList<>()); + } + + @NotNull + private HeadInfo readHeadInternal(@NotNull File headFile, @NotNull List alreadyVisited) { String headContent; try { - headContent = DvcsUtil.tryLoadFile(myHeadFile, CharsetToolkit.UTF8); + headContent = DvcsUtil.tryLoadFile(headFile, CharsetToolkit.UTF8); } catch (RepoStateException e) { LOG.error(e); @@ -331,11 +337,22 @@ class GitRepositoryReader { Hash hash = parseHash(headContent); if (hash != null) { - return new HeadInfo(false, headContent); + if (alreadyVisited.isEmpty()) { + return new HeadInfo(false, headContent); + } else { + return new HeadInfo(true, ContainerUtil.getLastItem(alreadyVisited)); + } } String target = getTarget(headContent); if (target != null) { - return new HeadInfo(true, target); + if (alreadyVisited.contains(target)) { + alreadyVisited.add(target); + LOG.error(new RepoStateException("Cyclic symbolic ref in HEAD: [" + StringUtil.join(alreadyVisited, " -> ") + "]")); + return new HeadInfo(false, null); + } else { + alreadyVisited.add(target); + return readHeadInternal(myGitFiles.getBranchFile(target), alreadyVisited); + } } LOG.error(new RepoStateException("Invalid format of the .git/HEAD file: [" + headContent + "]")); // including "refs/tags/v1" return new HeadInfo(false, null); diff --git a/plugins/git4idea/testData/repo/symbolic-refs/current-branch.txt b/plugins/git4idea/testData/repo/symbolic-refs/current-branch.txt index 30e2c01a2f94..c9d930435819 100644 --- a/plugins/git4idea/testData/repo/symbolic-refs/current-branch.txt +++ b/plugins/git4idea/testData/repo/symbolic-refs/current-branch.txt @@ -1 +1 @@ -0e1d130689bc52f140c5c374aa9cc2b8916c0ad7 master-link \ No newline at end of file +0e1d130689bc52f140c5c374aa9cc2b8916c0ad7 master