void (List<? extends Change> changes, List<VcsException> vcsExceptions, @NotNull RollbackProgressListener listener) { if (changes == null || changes.isEmpty()) { return; } List<FilePath> toDelete = new ArrayList<>(); List<FilePath> filePaths = new LinkedList<>(); for (Change change : changes) { ContentRevision contentRevision; if (Change.Type.DELETED == change.getType()) { contentRevision = change.getBeforeRevision(); } else { contentRevision = change.getAfterRevision(); } if (contentRevision != null) { filePaths.add(contentRevision.getFile()); if (Change.Type.MOVED == change.getType()) { toDelete.add(contentRevision.getFile()); } } } try (AccessToken ignore = DvcsUtil.workingTreeChangeStarted(project, getRollbackOperationName())) { revert(filePaths); for (FilePath file : toDelete) { listener.accept(file); try { final File ioFile = file.getIOFile(); if (ioFile.exists()) { if (!ioFile.delete()) { vcsExceptions.add(new VcsException(HgBundle.message("error.cannot.delete.file", file.getPresentableUrl()))); } } } catch (Exception e) { vcsExceptions.add(new VcsException(HgBundle.message("error.cannot.delete.file", file.getPresentableUrl()), e)); } } } }