void (@NotNull final AnActionEvent e) { Project project = e.getRequiredData(CommonDataKeys.PROJECT); ChangesListView view = e.getRequiredData(ChangesListView.DATA_KEY); if (ChangeListManager.getInstance(project).isFreezedWithNotification(null)) return; List<Change> changes = view.getSelectedChanges().toList(); List<FilePath> unversioned = view.getSelectedUnversionedFiles().toList(); final boolean needsConversion = checkIfThereAreFakeRevisions(project, changes); DiffRequestChain chain; if (needsConversion) { CompletableFuture<ListSelection<Producer>> resultRef = new CompletableFuture<>(); // this trick is essential since we are under some conditions to refresh changes; // but we can only rely on callback after refresh ChangeListManager.getInstance(project).invokeAfterUpdate(true, () -> { ChangesViewManager.getInstanceEx(project).promiseRefresh().onProcessed(__ -> { try { List<Change> actualChanges = loadFakeRevisions(project, changes); resultRef.complete(collectRequestProducers(project, actualChanges, unversioned, view)); } catch (Throwable err) { resultRef.completeExceptionally(err); } }); }); chain = new ChangeDiffRequestChain.Async() { @Override protected @NotNull ListSelection<? extends Producer> loadRequestProducers() throws DiffRequestProducerException { try { return resultRef.get(); } catch (InterruptedException | ExecutionException ex) { throw new DiffRequestProducerException(ex); } } }; } else { ListSelection<Producer> producers = collectRequestProducers(project, changes, unversioned, view); if (producers.isEmpty()) return; chain = new ChangeDiffRequestChain(producers); } chain.putUserData(DiffUserDataKeysEx.LAST_REVISION_WITH_LOCAL, true); setAllowExcludeFromCommit(project, chain); DiffManager.getInstance().showDiff(project, chain, DiffDialogHints.DEFAULT); }