boolean resetOnEvents(@NotNull List<? extends VFileEvent> events) { for (VFileEvent event : events) { VirtualFile file = event.getFile(); if (file == null || file.isDirectory()) { return true; } } return false; }
@NotNull private static List<VFileEvent> validateEvents(@NotNull List<VFileEvent> events) { final List<EventWrapper> deletionEvents = ContainerUtil.newArrayList(); for (int i = 0, size = events.size(); i < size; i++) { final VFileEvent event = events.get(i); if (event instanceof VFileDeleteEvent && event.isValid()) { deletionEvents.add(new EventWrapper((VFileDeleteEvent) event, i)); } } final TIntHashSet invalidIDs; if (deletionEvents.isEmpty()) { invalidIDs = EmptyIntHashSet.INSTANCE; } else { ContainerUtil.quickSort(deletionEvents, DEPTH_COMPARATOR); invalidIDs = new TIntHashSet(deletionEvents.size()); final Set<VirtualFile> dirsToBeDeleted = new THashSet<VirtualFile>(deletionEvents.size()); nextEvent: for (EventWrapper wrapper : deletionEvents) { final VirtualFile candidate = wrapper.event.getFile(); VirtualFile parent = candidate; while (parent != null) { if (dirsToBeDeleted.contains(parent)) { invalidIDs.add(wrapper.id); continue nextEvent; } parent = parent.getParent(); } if (candidate.isDirectory()) { dirsToBeDeleted.add(candidate); } } } final List<VFileEvent> filtered = new ArrayList<VFileEvent>(events.size() - invalidIDs.size()); for (int i = 0, size = events.size(); i < size; i++) { final VFileEvent event = events.get(i); if (event.isValid() && !(event instanceof VFileDeleteEvent && invalidIDs.contains(i))) { filtered.add(event); } } return filtered; }
private void assertEvent(Class<? extends VFileEvent> type, String... paths) { List<VFileEvent> events = getEvents(type.getSimpleName(), null); assertEquals(events.toString(), paths.length, events.size()); Set<String> pathSet = ContainerUtil.map2Set( paths, new Function<String, String>() { @Override public String fun(final String path) { return FileUtil.toSystemIndependentName(path); } }); for (VFileEvent event : events) { assertTrue(event.toString(), type.isInstance(event)); VirtualFile eventFile = event.getFile(); assertNotNull(event.toString(), eventFile); assertTrue( eventFile + " not in " + Arrays.toString(paths), pathSet.remove(eventFile.getPath())); } }
@Override public void after(@NotNull List<? extends VFileEvent> events) { // which files in .git were changed boolean configChanged = false; boolean headChanged = false; boolean branchFileChanged = false; boolean packedRefsChanged = false; boolean rebaseFileChanged = false; boolean mergeFileChanged = false; for (VFileEvent event : events) { final VirtualFile file = event.getFile(); if (file == null) { continue; } String filePath = GitFileUtils.stripFileProtocolPrefix(file.getPath()); if (myRepositoryFiles.isConfigFile(filePath)) { configChanged = true; } else if (myRepositoryFiles.isHeadFile(filePath)) { headChanged = true; } else if (myRepositoryFiles.isBranchFile(filePath)) { // it is also possible, that a local branch with complex name ("myfolder/mybranch") was // created => the folder also to be watched. branchFileChanged = true; visitAllChildrenRecursively(myHeadsDir); } else if (myRepositoryFiles.isRemoteBranchFile(filePath)) { // it is possible, that a branch from a new remote was fetch => we need to add new remote // folder to the VFS branchFileChanged = true; visitAllChildrenRecursively(myRemotesDir); } else if (myRepositoryFiles.isPackedRefs(filePath)) { packedRefsChanged = true; } else if (myRepositoryFiles.isRebaseFile(filePath)) { rebaseFileChanged = true; } else if (myRepositoryFiles.isMergeFile(filePath)) { mergeFileChanged = true; } } // what should be updated in GitRepository boolean updateCurrentBranch = false; boolean updateCurrentRevision = false; boolean updateState = false; boolean updateBranches = false; if (headChanged) { updateCurrentBranch = true; updateCurrentRevision = true; updateState = true; } if (branchFileChanged) { updateCurrentRevision = true; updateBranches = true; } if (rebaseFileChanged || mergeFileChanged) { updateState = true; } if (packedRefsChanged) { updateCurrentBranch = true; updateBranches = true; } // update GitRepository on pooled thread, because it requires reading from disk and parsing // data. if (updateCurrentBranch) { myUpdateQueue.add(GitRepository.TrackedTopic.CURRENT_BRANCH); } if (updateCurrentRevision) { myUpdateQueue.add(GitRepository.TrackedTopic.CURRENT_REVISION); } if (updateState) { myUpdateQueue.add(GitRepository.TrackedTopic.STATE); } if (updateBranches) { myUpdateQueue.add(GitRepository.TrackedTopic.BRANCHES); } if (configChanged) { myUpdateQueue.add(GitRepository.TrackedTopic.CONFIG); } }
/** * Allows to distinguish file events from MPS code and from IDEA platform code We don't process * events on file updates from MPS * * @param event * @return true - event is from IdeaFile processing, false - event from refresh or any other * VirtualFile changes */ public static boolean isFileEventFromMPS(VFileEvent event) { return event.getRequestor() instanceof IdeaFileSystemProvider; }
@Nullable private static VirtualFile getFileForEvent(VFileEvent event) { return VcsUtil.getVirtualFile(event.getPath()); }