From b421683523918152ef28696ff8b5e48a50c74029 Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Sun, 29 Nov 2015 13:54:58 +0300 Subject: [PATCH] [git] Refresh local changes also if HEAD changes, or if current branch head changes Relates to IDEA-100199 --- .../src/git4idea/repo/GitRepositoryFiles.java | 41 ++++++++++++------- .../repo/GitUntrackedFilesHolder.java | 15 ++++++- 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/plugins/git4idea/src/git4idea/repo/GitRepositoryFiles.java b/plugins/git4idea/src/git4idea/repo/GitRepositoryFiles.java index 217b665deaae..f6da0f99053b 100644 --- a/plugins/git4idea/src/git4idea/repo/GitRepositoryFiles.java +++ b/plugins/git4idea/src/git4idea/repo/GitRepositoryFiles.java @@ -15,6 +15,7 @@ */ package git4idea.repo; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VirtualFile; import git4idea.util.GitFileUtils; import org.jetbrains.annotations.NotNull; @@ -57,6 +58,7 @@ public class GitRepositoryFiles { public static final String GIT_SQUASH_MSG = DOT_GIT + slash(SQUASH_MSG); public static final String GIT_COMMIT_EDITMSG = DOT_GIT + slash(COMMIT_EDITMSG); + private final String myGitDirPath; private final String myConfigFilePath; private final String myHeadFilePath; private final String myIndexFilePath; @@ -79,20 +81,20 @@ public class GitRepositoryFiles { private GitRepositoryFiles(@NotNull VirtualFile gitDir) { // add .git/ and .git/refs/heads to the VFS // save paths of the files, that we will watch - String gitDirPath = GitFileUtils.stripFileProtocolPrefix(gitDir.getPath()); - myConfigFilePath = gitDirPath + slash(CONFIG); - myHeadFilePath = gitDirPath + slash(HEAD); - myIndexFilePath = gitDirPath + slash(INDEX); - myMergeHeadPath = gitDirPath + slash(MERGE_HEAD); - myOrigHeadPath = gitDirPath + slash(ORIG_HEAD); - myCommitMessagePath = gitDirPath + slash(COMMIT_EDITMSG); - myRebaseApplyPath = gitDirPath + slash(REBASE_APPLY); - myRebaseMergePath = gitDirPath + slash(REBASE_MERGE); - myPackedRefsPath = gitDirPath + slash(PACKED_REFS); - myRefsHeadsDirPath = gitDirPath + slash(REFS_HEADS); - myRefsTagsPath = gitDirPath + slash(REFS_TAGS); - myRefsRemotesDirPath = gitDirPath + slash(REFS_REMOTES); - myExcludePath = gitDirPath + slash(INFO_EXCLUDE); + myGitDirPath = GitFileUtils.stripFileProtocolPrefix(gitDir.getPath()); + myConfigFilePath = myGitDirPath + slash(CONFIG); + myHeadFilePath = myGitDirPath + slash(HEAD); + myIndexFilePath = myGitDirPath + slash(INDEX); + myMergeHeadPath = myGitDirPath + slash(MERGE_HEAD); + myOrigHeadPath = myGitDirPath + slash(ORIG_HEAD); + myCommitMessagePath = myGitDirPath + slash(COMMIT_EDITMSG); + myRebaseApplyPath = myGitDirPath + slash(REBASE_APPLY); + myRebaseMergePath = myGitDirPath + slash(REBASE_MERGE); + myPackedRefsPath = myGitDirPath + slash(PACKED_REFS); + myRefsHeadsDirPath = myGitDirPath + slash(REFS_HEADS); + myRefsTagsPath = myGitDirPath + slash(REFS_TAGS); + myRefsRemotesDirPath = myGitDirPath + slash(REFS_REMOTES); + myExcludePath = myGitDirPath + slash(INFO_EXCLUDE); } @NotNull @@ -158,6 +160,17 @@ public class GitRepositoryFiles { return filePath.startsWith(myRefsHeadsDirPath); } + /** + * Checks if the given filePath represents the ref file of the given branch. + * + * @param filePath the path to check, in system-independent format (e.g. with "/"). + * @param fullBranchName full name of a ref, e.g. {@code refs/heads/master}. + * @return true iff the filePath represents the .git/refs/heads... file for the given branch. + */ + public boolean isBranchFile(@NotNull String filePath, @NotNull String fullBranchName) { + return FileUtil.pathsEqual(filePath, myGitDirPath + slash(fullBranchName)); + } + /** * Any file in .git/refs/remotes, i.e. a remote branch reference file. */ diff --git a/plugins/git4idea/src/git4idea/repo/GitUntrackedFilesHolder.java b/plugins/git4idea/src/git4idea/repo/GitUntrackedFilesHolder.java index 41c53e50149d..c1139a94311b 100644 --- a/plugins/git4idea/src/git4idea/repo/GitUntrackedFilesHolder.java +++ b/plugins/git4idea/src/git4idea/repo/GitUntrackedFilesHolder.java @@ -28,6 +28,7 @@ import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.openapi.vfs.newvfs.BulkFileListener; import com.intellij.openapi.vfs.newvfs.events.*; import com.intellij.util.messages.MessageBusConnection; +import git4idea.GitLocalBranch; import git4idea.GitUtil; import git4idea.commands.Git; import org.jetbrains.annotations.NotNull; @@ -88,6 +89,7 @@ public class GitUntrackedFilesHolder implements Disposable, BulkFileListener { private final Project myProject; private final VirtualFile myRoot; + private final GitRepository myRepository; private final ChangeListManager myChangeListManager; private final VcsDirtyScopeManager myDirtyScopeManager; private final ProjectLevelVcsManager myVcsManager; @@ -102,6 +104,7 @@ public class GitUntrackedFilesHolder implements Disposable, BulkFileListener { GitUntrackedFilesHolder(@NotNull GitRepository repository) { myProject = repository.getProject(); + myRepository = repository; myRoot = repository.getRoot(); myChangeListManager = ChangeListManager.getInstance(myProject); myDirtyScopeManager = VcsDirtyScopeManager.getInstance(myProject); @@ -266,7 +269,17 @@ public class GitUntrackedFilesHolder implements Disposable, BulkFileListener { } private boolean totalRefreshNeeded(@NotNull String path) { - return indexChanged(path) || externallyCommitted(path) || headMoved(path) || gitignoreChanged(path); + return indexChanged(path) || externallyCommitted(path) || headMoved(path) || + headChanged(path) || currentBranchChanged(path) || gitignoreChanged(path); + } + + private boolean headChanged(@NotNull String path) { + return myRepositoryFiles.isHeadFile(path); + } + + private boolean currentBranchChanged(@NotNull String path) { + GitLocalBranch currentBranch = myRepository.getCurrentBranch(); + return currentBranch != null && myRepositoryFiles.isBranchFile(path, currentBranch.getFullName()); } private boolean headMoved(@NotNull String path) {