ProcessingResult (@NotNull Change change, @NotNull IncomingChangeListData changeListData, @Nullable Collection<FilePath> incomingFiles) { final CommittedChangeList changeList = changeListData.changeList; final ContentRevision afterRevision = change.getAfterRevision(); if (afterRevision != null) { if (afterRevision.getFile().isNonLocal()) { // don't bother to search for non-local paths on local disk return new ProcessingResult(true, AFTER_DOES_NOT_MATTER_NON_LOCAL); } if (change.getBeforeRevision() == null) { final FilePath path = afterRevision.getFile(); debug("Marking created file " + path); myCreatedFiles.add(path); } else if (change.getBeforeRevision().getFile().getPath().equals(afterRevision.getFile().getPath()) && change.isIsReplaced()) { myReplacedFiles.add(afterRevision.getFile()); } if (incomingFiles != null && !incomingFiles.contains(afterRevision.getFile())) { debug("Skipping new/changed file outside of incoming files: " + afterRevision.getFile()); return new ProcessingResult(true, AFTER_DOES_NOT_MATTER_OUTSIDE_INCOMING); } debug("Checking file " + afterRevision.getFile().getPath()); FilePath localPath = ChangesUtil.getLocalPath(myProject, afterRevision.getFile()); if (! FileUtil.isAncestor(myChangesCacheFile.myRootPath.getIOFile(), localPath.getIOFile(), false)) { // alien change in list; skip debug("Alien path " + localPath.getPresentableUrl() + " under root " + myChangesCacheFile.myRootPath.getPresentableUrl() + "; skipping."); return new ProcessingResult(true, AFTER_DOES_NOT_MATTER_ALIEN_PATH); } final VirtualFile file = localPath.getVirtualFile(); if (isDeletedFile(myDeletedFiles, afterRevision, myReplacedFiles)) { debug("Found deleted file"); return new ProcessingResult(true, AFTER_DOES_NOT_MATTER_DELETED_FOUND_IN_INCOMING_LIST); } else if (file != null) { return new ProcessingResult(file, revision -> { if (revision != null) { debug("Current revision is " + revision + ", changelist revision is " + afterRevision.getRevisionNumber()); //noinspection unchecked if (myChangesCacheFile.myChangesProvider .isChangeLocallyAvailable(afterRevision.getFile(), revision, afterRevision.getRevisionNumber(), changeList)) { return new ProcessingResult(true, AFTER_EXISTS_LOCALLY_AVAILABLE); } return new ProcessingResult(false, AFTER_EXISTS_NOT_LOCALLY_AVAILABLE); } debug("Failed to fetch revision"); return new ProcessingResult(false, AFTER_EXISTS_REVISION_NOT_LOADED); }); } else { //noinspection unchecked if (myChangesCacheFile.myChangesProvider.isChangeLocallyAvailable(afterRevision.getFile(), null, afterRevision.getRevisionNumber(), changeList)) { return new ProcessingResult(true, AFTER_NOT_EXISTS_LOCALLY_AVAILABLE); } if (fileMarkedForDeletion(localPath)) { debug("File marked for deletion and not committed jet."); return new ProcessingResult(true, AFTER_NOT_EXISTS_MARKED_FOR_DELETION); } if (wasSubsequentlyDeleted(afterRevision.getFile(), changeListData.indexOffset)) { return new ProcessingResult(true, AFTER_NOT_EXISTS_SUBSEQUENTLY_DELETED); } debug("Could not find local file for change " + afterRevision.getFile().getPath()); return new ProcessingResult(false, AFTER_NOT_EXISTS_OTHER); } } else { final ContentRevision beforeRevision = change.getBeforeRevision(); assert beforeRevision != null; debug("Checking deleted file " + beforeRevision.getFile()); myDeletedFiles.add(beforeRevision.getFile()); if (incomingFiles != null && !incomingFiles.contains(beforeRevision.getFile())) { debug("Skipping deleted file outside of incoming files: " + beforeRevision.getFile()); return new ProcessingResult(true, BEFORE_DOES_NOT_MATTER_OUTSIDE); } if (beforeRevision.getFile().getVirtualFile() == null || myCreatedFiles.contains(beforeRevision.getFile())) { // if not deleted from vcs, mark as incoming, otherwise file already deleted final boolean locallyDeleted = ChangeListManagerImpl.getInstanceImpl(myProject) .isContainedInLocallyDeleted(beforeRevision.getFile()); debug(locallyDeleted ? "File deleted locally, change marked as incoming" : "File already deleted"); return new ProcessingResult(!locallyDeleted, locallyDeleted ? BEFORE_NOT_EXISTS_DELETED_LOCALLY : BEFORE_NOT_EXISTS_ALREADY_DELETED); } else if (!myChangesCacheFile.myVcs.fileExistsInVcs(beforeRevision.getFile())) { debug("File exists locally and is unversioned"); return new ProcessingResult(true, BEFORE_UNVERSIONED_INSTEAD_OF_VERS_DELETED); } else { final VirtualFile file = beforeRevision.getFile().getVirtualFile(); return new ProcessingResult(file, currentRevision -> { if ((currentRevision != null) && (currentRevision.compareTo(beforeRevision.getRevisionNumber()) > 0)) { // revived in newer revision - possibly was added file with same name debug("File with same name was added after file deletion"); return new ProcessingResult(true, BEFORE_SAME_NAME_ADDED_AFTER_DELETION); } debug("File exists locally and no 'create' change found for it"); return new ProcessingResult(false, BEFORE_EXISTS_BUT_SHOULD_NOT); }); } } }