GitRepositoryManager: update on .git dir change, not on mappings change

This solves IDEA-64973 ("Enable Git Integration" => mapping is changed => GitRepositoryManager gets notified before git init happens => fails to create a GitRepository and shows a notification).
This also handles the case when a registered git repository was created or deleted outside IDEA - now it will be captured.

updateRepositoriesCollection() is called on startup now to initially collect the repositories.
For this GitRepositoryManager.getInstance() is removed from GitUntrackedFilesHolder constructor (otherwise it leads to a cyclic dependency).

Git root rescan happens on every updateRepositoriesCollection().
This commit is contained in:
Kirill Likhodedov
2012-03-06 17:53:27 +04:00
parent 9a910b8466
commit 1935c17044
2 changed files with 27 additions and 9 deletions
@@ -23,8 +23,10 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vcs.AbstractVcs;
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vcs.VcsListener;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.newvfs.BulkFileListener;
import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
import com.intellij.util.ArrayUtil;
import git4idea.PlatformFacade;
import git4idea.roots.GitRootProblemNotifier;
@@ -40,7 +42,7 @@ import static git4idea.GitUtil.sortRepositories;
* GitRepositoryManager initializes and stores {@link GitRepository GitRepositories} for Git roots defined in the project.
* @author Kirill Likhodedov
*/
public final class GitRepositoryManager extends AbstractProjectComponent implements Disposable, VcsListener {
public final class GitRepositoryManager extends AbstractProjectComponent implements Disposable {
private static final Logger LOG = Logger.getInstance(GitRepositoryManager.class);
@@ -67,8 +69,9 @@ public final class GitRepositoryManager extends AbstractProjectComponent impleme
@Override
public void initComponent() {
myProject.getMessageBus().connect().subscribe(ProjectLevelVcsManager.VCS_CONFIGURATION_CHANGED, this);
myProject.getMessageBus().connect().subscribe(VirtualFileManager.VFS_CHANGES, new MyRepositoryCreationDeletionListener());
Disposer.register(myProject, this);
updateRepositoriesCollection();
}
@Override
@@ -159,8 +162,7 @@ public final class GitRepositoryManager extends AbstractProjectComponent impleme
}
// note: we are not calling this method during the project startup - it is called anyway by the GitRootTracker
@Override
public void directoryMappingChanged() {
private void updateRepositoriesCollection() {
try {
REPO_LOCK.writeLock().lock();
final VirtualFile[] roots = myVcsManager.getRootsUnderVcs(myVcs);
@@ -179,10 +181,12 @@ public final class GitRepositoryManager extends AbstractProjectComponent impleme
}
else {
LOG.info("Invalid Git root: " + root);
GitRootProblemNotifier.getInstance(myProject, myPlatformFacade).rescanAndNotifyIfNeeded();
}
}
}
GitRootProblemNotifier.getInstance(myProject, myPlatformFacade).rescanAndNotifyIfNeeded();
}
finally {
REPO_LOCK.writeLock().unlock();
@@ -206,4 +210,20 @@ public final class GitRepositoryManager extends AbstractProjectComponent impleme
public String toString() {
return "GitRepositoryManager{myRepositories: " + myRepositories + '}';
}
private class MyRepositoryCreationDeletionListener implements BulkFileListener {
@Override
public void before(@NotNull List<? extends VFileEvent> events) {
}
@Override
public void after(@NotNull List<? extends VFileEvent> events) {
for (VFileEvent event : events) {
VirtualFile file = event.getFile();
if (file != null && file.getName().equalsIgnoreCase(".git") && file.isDirectory()) {
updateRepositoriesCollection();
}
}
}
}
}
@@ -79,7 +79,6 @@ public class GitUntrackedFilesHolder implements Disposable, BulkFileListener {
private final Project myProject;
private final VirtualFile myRoot;
private final ChangeListManager myChangeListManager;
private final GitRepositoryManager myRepositoryManager;
private final VcsDirtyScopeManager myDirtyScopeManager;
private final GitRepositoryFiles myRepositoryFiles;
private final Git myGit;
@@ -95,7 +94,6 @@ public class GitUntrackedFilesHolder implements Disposable, BulkFileListener {
myRoot = root;
myRepositoryFiles = GitRepositoryFiles.getInstance(root);
myChangeListManager = ChangeListManager.getInstance(project);
myRepositoryManager = GitRepositoryManager.getInstance(project);
myDirtyScopeManager = VcsDirtyScopeManager.getInstance(project);
myGit = ServiceManager.getService(Git.class);
}
@@ -297,7 +295,7 @@ public class GitUntrackedFilesHolder implements Disposable, BulkFileListener {
}
private boolean belongsToThisRepository(VirtualFile file) {
final GitRepository repository = myRepositoryManager.getRepositoryForFile(file);
final GitRepository repository = GitRepositoryManager.getInstance(myProject).getRepositoryForFile(file);
return repository != null && repository.getRoot().equals(myRoot);
}