mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[file-history] move code for loading diff in background to GitLogDiffHandler
Reuse the code in all diff kinds. This way actions would not need to manage background execution themselves.
This commit is contained in:
@@ -16,7 +16,6 @@
|
||||
package com.intellij.vcs.log;
|
||||
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -24,10 +23,9 @@ import org.jetbrains.annotations.Nullable;
|
||||
public interface VcsLogDiffHandler {
|
||||
void showDiff(@NotNull VirtualFile root,
|
||||
@Nullable FilePath leftPath, @NotNull Hash leftHash,
|
||||
@Nullable FilePath rightPath, @NotNull Hash rightHash) throws VcsException;
|
||||
@Nullable FilePath rightPath, @NotNull Hash rightHash);
|
||||
|
||||
void showDiffWithLocal(@NotNull VirtualFile root,
|
||||
@Nullable FilePath revisionPath,
|
||||
@NotNull Hash hash, @NotNull FilePath localPath)
|
||||
throws VcsException;
|
||||
@NotNull Hash hash, @NotNull FilePath localPath);
|
||||
}
|
||||
|
||||
+1
-18
@@ -117,24 +117,7 @@ public class CompareRevisionsFromHistoryAction extends AnAction implements DumbA
|
||||
// so that it could return a single file path for each revision
|
||||
VcsFullCommitDetails newestDetail = details.get(0);
|
||||
VcsFullCommitDetails olderDetail = details.get(1);
|
||||
ProgressIndicator indicator = ui.getLogData().getProgress().createProgressIndicator(true);
|
||||
ProgressManager.getInstance()
|
||||
.runProcessWithProgressAsynchronously(new Task.Backgroundable(project, "Comparing Revisions...", false) {
|
||||
@Override
|
||||
public void run(@NotNull ProgressIndicator indicator) {
|
||||
try {
|
||||
notNull(handler).showDiff(root, ui.getPath(olderDetail), olderDetail.getId(), ui.getPath(newestDetail), newestDetail.getId());
|
||||
}
|
||||
catch (VcsException e1) {
|
||||
VcsBalloonProblemNotifier.showOverVersionControlView(project, "Could not compare revisions " +
|
||||
olderDetail.getId().asString() +
|
||||
" and " +
|
||||
newestDetail.getId().asString() +
|
||||
"\n" +
|
||||
e1.getMessage(), MessageType.ERROR);
|
||||
}
|
||||
}
|
||||
}, indicator);
|
||||
notNull(handler).showDiff(root, ui.getPath(olderDetail), olderDetail.getId(), ui.getPath(newestDetail), newestDetail.getId());
|
||||
}
|
||||
else if (details.size() == 1) {
|
||||
VcsFullCommitDetails detail = notNull(ContainerUtil.getFirstItem(details));
|
||||
|
||||
@@ -23,15 +23,21 @@ import com.intellij.diff.contents.EmptyContent;
|
||||
import com.intellij.diff.requests.DiffRequest;
|
||||
import com.intellij.diff.requests.SimpleDiffRequest;
|
||||
import com.intellij.diff.util.DiffUserDataKeysEx;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.progress.Task;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.MessageType;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.ThrowableComputable;
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.changes.Change;
|
||||
import com.intellij.openapi.vcs.history.VcsDiffUtil;
|
||||
import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.WaitForProgressToShow;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.vcs.log.Hash;
|
||||
import com.intellij.vcs.log.VcsLogDiffHandler;
|
||||
@@ -39,11 +45,11 @@ import com.intellij.vcsUtil.VcsFileUtil;
|
||||
import git4idea.GitRevisionNumber;
|
||||
import git4idea.changes.GitChangeUtils;
|
||||
import git4idea.util.GitFileUtils;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -65,87 +71,131 @@ public class GitLogDiffHandler implements VcsLogDiffHandler {
|
||||
@Nullable FilePath leftPath,
|
||||
@NotNull Hash leftHash,
|
||||
@Nullable FilePath rightPath,
|
||||
@NotNull Hash rightHash) throws VcsException {
|
||||
@NotNull Hash rightHash) {
|
||||
if (leftPath == null && rightPath == null) return;
|
||||
|
||||
if (chooseNotNull(leftPath, rightPath).isDirectory()) {
|
||||
showDiffForDirectory(root, chooseNotNull(leftPath, rightPath), leftHash, rightHash);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
DiffContent leftDiffContent = createDiffContent(root, leftPath, leftHash);
|
||||
DiffContent rightDiffContent = createDiffContent(root, rightPath, rightHash);
|
||||
loadDiffAndShow(new ThrowableComputable<DiffRequest, VcsException>() {
|
||||
@Override
|
||||
public DiffRequest compute() throws VcsException {
|
||||
DiffContent leftDiffContent = createDiffContent(root, leftPath, leftHash);
|
||||
DiffContent rightDiffContent = createDiffContent(root, rightPath, rightHash);
|
||||
|
||||
DiffRequest request = new SimpleDiffRequest(getTitle(leftPath, rightPath),
|
||||
leftDiffContent, rightDiffContent,
|
||||
leftHash.asString(), rightHash.asString());
|
||||
|
||||
WaitForProgressToShow.runOrInvokeLaterAboveProgress(() -> DiffManager.getInstance().showDiff(myProject, request), null, myProject);
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
return new SimpleDiffRequest(getTitle(leftPath, rightPath),
|
||||
leftDiffContent, rightDiffContent,
|
||||
leftHash.asString(), rightHash.asString());
|
||||
}
|
||||
},
|
||||
request -> DiffManager.getInstance().showDiff(myProject, request),
|
||||
"Calculating Diff for " + chooseNotNull(rightPath, leftPath).getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showDiffWithLocal(@NotNull VirtualFile root, @Nullable FilePath revisionPath, @NotNull Hash revisionHash,
|
||||
@NotNull FilePath localPath)
|
||||
throws VcsException {
|
||||
@NotNull FilePath localPath) {
|
||||
if (localPath.isDirectory()) {
|
||||
showDiffForDirectory(root, localPath, revisionHash, null);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
DiffContent leftDiffContent = createDiffContent(root, revisionPath, revisionHash);
|
||||
loadDiffAndShow(new ThrowableComputable<DiffRequest, VcsException>() {
|
||||
@Override
|
||||
public DiffRequest compute() throws VcsException {
|
||||
DiffContent leftDiffContent = createDiffContent(root, revisionPath, revisionHash);
|
||||
|
||||
VirtualFile file = localPath.getVirtualFile();
|
||||
LOG.assertTrue(file != null);
|
||||
DiffContent rightDiffContent = myDiffContentFactory.create(myProject, file);
|
||||
VirtualFile file = localPath.getVirtualFile();
|
||||
LOG.assertTrue(file != null);
|
||||
DiffContent rightDiffContent = myDiffContentFactory.create(myProject, file);
|
||||
|
||||
DiffRequest request = new SimpleDiffRequest(getTitle(revisionPath, localPath),
|
||||
leftDiffContent, rightDiffContent,
|
||||
revisionHash.asString(), "(Local)");
|
||||
|
||||
WaitForProgressToShow.runOrInvokeLaterAboveProgress(() -> DiffManager.getInstance().showDiff(myProject, request), null, myProject);
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
return new SimpleDiffRequest(getTitle(revisionPath, localPath),
|
||||
leftDiffContent, rightDiffContent,
|
||||
revisionHash.asString(), "(Local)");
|
||||
}
|
||||
},
|
||||
request -> DiffManager.getInstance().showDiff(myProject, request), "Calculating Diff for " + localPath.getName());
|
||||
}
|
||||
}
|
||||
|
||||
private void showDiffForDirectory(@NotNull VirtualFile root,
|
||||
@NotNull FilePath directoryPath,
|
||||
@NotNull Hash leftRevision, @Nullable Hash rightRevision) throws VcsException {
|
||||
Collection<Change> diff = GitChangeUtils.getDiff(myProject, root,
|
||||
leftRevision.asString(), rightRevision == null ? null : rightRevision.asString(),
|
||||
Collections.singleton(directoryPath));
|
||||
WaitForProgressToShow.runOrInvokeLaterAboveProgress(() -> {
|
||||
String dialogTitle = "Changes between " +
|
||||
leftRevision.asString() +
|
||||
" and " +
|
||||
(rightRevision == null ? "current revision" : rightRevision.asString()) +
|
||||
" in " +
|
||||
getTitle(directoryPath, directoryPath);
|
||||
VcsDiffUtil.showChangesDialog(myProject, dialogTitle,
|
||||
ContainerUtil.newArrayList(diff));
|
||||
},
|
||||
null,
|
||||
myProject);
|
||||
@NotNull Hash leftRevision, @Nullable Hash rightRevision) {
|
||||
loadDiffAndShow(() -> GitChangeUtils.getDiff(myProject, root,
|
||||
leftRevision.asString(), rightRevision == null ? null : rightRevision.asString(),
|
||||
Collections.singleton(directoryPath)),
|
||||
(diff) -> {
|
||||
String dialogTitle = "Changes between " +
|
||||
leftRevision.asString() +
|
||||
" and " +
|
||||
(rightRevision == null ? "current revision" : rightRevision.asString()) +
|
||||
" in " +
|
||||
getTitle(directoryPath, directoryPath);
|
||||
VcsDiffUtil.showChangesDialog(myProject, dialogTitle, ContainerUtil.newArrayList(diff));
|
||||
}, "Calculating Diff for " + directoryPath.getName());
|
||||
}
|
||||
|
||||
private <T> void loadDiffAndShow(@NotNull ThrowableComputable<T, VcsException> load,
|
||||
@NotNull Consumer<T> show,
|
||||
@NotNull @Nls(capitalization = Nls.Capitalization.Title) String title) {
|
||||
if (ApplicationManager.getApplication().isDispatchThread()) {
|
||||
ProgressManager.getInstance().run(new Task.Backgroundable(myProject, title + "...", false) {
|
||||
@Nullable private T myResult;
|
||||
|
||||
@Override
|
||||
public void run(@NotNull ProgressIndicator indicator) {
|
||||
try {
|
||||
myResult = load.compute();
|
||||
}
|
||||
catch (VcsException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
if (myResult != null) {
|
||||
show.consume(myResult);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onThrowable(@NotNull Throwable error) {
|
||||
VcsBalloonProblemNotifier.showOverVersionControlView(myProject, title + " failed\n" +
|
||||
error.getMessage(), MessageType.ERROR);
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
try {
|
||||
T result = load.compute();
|
||||
ApplicationManager.getApplication().invokeLater(() -> show.consume(result));
|
||||
}
|
||||
catch (VcsException e) {
|
||||
VcsBalloonProblemNotifier.showOverVersionControlView(myProject, title + " failed\n" +
|
||||
e.getMessage(), MessageType.ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private DiffContent createDiffContent(@NotNull VirtualFile root,
|
||||
@Nullable FilePath path,
|
||||
@NotNull Hash hash) throws IOException, VcsException {
|
||||
@NotNull Hash hash) throws VcsException {
|
||||
|
||||
DiffContent diffContent;
|
||||
if (path == null) {
|
||||
diffContent = new EmptyContent();
|
||||
}
|
||||
else {
|
||||
byte[] content = GitFileUtils.getFileContent(myProject, root, hash.asString(), VcsFileUtil.relativePath(root, path));
|
||||
diffContent = myDiffContentFactory.createFromBytes(myProject, content, path);
|
||||
try {
|
||||
byte[] content = GitFileUtils.getFileContent(myProject, root, hash.asString(), VcsFileUtil.relativePath(root, path));
|
||||
diffContent = myDiffContentFactory.createFromBytes(myProject, content, path);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new VcsException(e);
|
||||
}
|
||||
}
|
||||
|
||||
diffContent.putUserData(DiffUserDataKeysEx.REVISION_INFO, new Pair<>(path, new GitRevisionNumber(hash.asString())));
|
||||
|
||||
Reference in New Issue
Block a user