void (@NotNull Project project, @NotNull VirtualFile file, @NotNull @Nls String revNumTitle1, @NotNull @Nls String revNumTitle2, @NotNull ThrowableComputable<? extends Collection<Change>, ? extends VcsException> changesLoader) { if (file.isDirectory()) { String dialogTitle = VcsBundle.message("history.dialog.title.difference.between.versions.in", revNumTitle1, revNumTitle2, file.getName()); CompareWithLocalDialog.showChanges(project, dialogTitle, CompareWithLocalDialog.LocalContent.AFTER, changesLoader); } else { DiffRequestChain requestChain = new ChangeDiffRequestChain.Async() { @Override protected @NotNull ListSelection<ChangeDiffRequestProducer> loadRequestProducers() throws DiffRequestProducerException { try { Collection<Change> changes = changesLoader.compute(); Map<Key<?>, Object> changeContext = new HashMap<>(2); changeContext.put(DiffUserDataKeysEx.VCS_DIFF_LEFT_CONTENT_TITLE, revNumTitle1); changeContext.put(DiffUserDataKeysEx.VCS_DIFF_RIGHT_CONTENT_TITLE, revNumTitle2); return ListSelection.createAt(new ArrayList<>(changes), 0) .map(change -> ChangeDiffRequestProducer.create(project, change, changeContext)); } catch (VcsException e) { throw new DiffRequestProducerException(e); } } }; DiffManager.getInstance().showDiff(project, requestChain, DiffDialogHints.DEFAULT); } }