[git] Refresh local changes also if HEAD changes, or if current branch head changes

Relates to IDEA-100199
This commit is contained in:
Kirill Likhodedov
2015-11-29 13:54:58 +03:00
parent 6094cce6ee
commit b421683523
2 changed files with 41 additions and 15 deletions
@@ -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.
*/
@@ -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) {