IDEA-85560 Files are not refreshed and Pull Info is not shown after Git pull

Problem:
since pull is run in the background, GitRepositoryAction starts the final tasks (VFS refresh, delayed tasks execution) before the task completes.

Solution:
Introduce the flag-method executeFinalTasksSynchronously, and return false from the actions which are asynchronous and should call the tasks themselves.
These actions are pull and fetch (final tasks are not needed for the latter).
Execute delayed tasks of GitMergeUtil in AWT later, because now they are called on a pooled thread on certain actions.
This commit is contained in:
Kirill Likhodedov
2012-05-02 21:16:14 +04:00
parent 277356758d
commit ec181ff915
4 changed files with 56 additions and 23 deletions
@@ -51,4 +51,8 @@ public class GitFetch extends GitRepositoryAction {
});
}
@Override
protected boolean executeFinalTasksSynchronously() {
return false;
}
}
@@ -25,6 +25,7 @@ import com.intellij.openapi.vcs.update.ActionInfo;
import com.intellij.openapi.vfs.VirtualFile;
import git4idea.GitRevisionNumber;
import git4idea.GitUtil;
import git4idea.GitVcs;
import git4idea.commands.GitLineHandler;
import git4idea.commands.GitStandardProgressAnalyzer;
import git4idea.commands.GitTask;
@@ -114,6 +115,7 @@ public class GitPull extends GitRepositoryAction {
protected void onSuccess() {
GitMergeUtil.showUpdates(GitPull.this, project, exceptions, root, currentRev, beforeLabel, getActionName(), ActionInfo.UPDATE);
repositoryManager.updateRepository(root, GitRepository.TrackedTopic.ALL);
runFinalTasks(project, GitVcs.getInstance(project), affectedRoots, getActionName(), exceptions);
}
@Override
@@ -126,4 +128,8 @@ public class GitPull extends GitRepositoryAction {
}.queue();
}
@Override
protected boolean executeFinalTasksSynchronously() {
return false;
}
}
@@ -24,7 +24,6 @@ import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vcs.AbstractVcsHelper;
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vcs.TransactionRunnable;
import com.intellij.openapi.vcs.VcsException;
@@ -89,27 +88,37 @@ public abstract class GitRepositoryAction extends DumbAwareAction {
final VirtualFile defaultRoot = defaultRootVar;
final Set<VirtualFile> affectedRoots = new HashSet<VirtualFile>();
String actionName = getActionName();
AbstractVcsHelper helper = AbstractVcsHelper.getInstance(project);
//Runs the runnable inside the vcs transaction (if needed), collects all exceptions, commits/rollbacks transaction and returns all exceptions together.
List<VcsException> exceptions = helper.runTransactionRunnable(vcs, new TransactionRunnable() {
public void run(List<VcsException> exceptions) {
//noinspection unchecked
try {
perform(project, roots, defaultRoot, affectedRoots, exceptions);
}
catch (VcsException e) {
exceptions.add(e);
}
VcsFileUtil.refreshFiles(project, affectedRoots);
for (TransactionRunnable task : myDelayedTasks) {
task.run(exceptions);
}
}
}, null);
List<VcsException> exceptions = new ArrayList<VcsException>();
try {
perform(project, roots, defaultRoot, affectedRoots, exceptions);
}
catch (VcsException ex) {
exceptions.add(ex);
}
if (executeFinalTasksSynchronously()) {
runFinalTasks(project, vcs, affectedRoots, actionName, exceptions);
}
}
protected final void runFinalTasks(Project project, GitVcs vcs, Set<VirtualFile> affectedRoots, String actionName,
List<VcsException> exceptions) {
VcsFileUtil.refreshFiles(project, affectedRoots);
for (TransactionRunnable task : myDelayedTasks) {
task.run(exceptions);
}
myDelayedTasks.clear();
vcs.showErrors(exceptions, actionName);
}
/**
* Return true to indicate that the final tasks should be executed after the action invocation,
* false if the task is responsible to call the final tasks manually via {@link #runFinalTasks(Project, GitVcs, Set, String, List)}.
*/
protected boolean executeFinalTasksSynchronously() {
return true;
}
protected static boolean isRebasing(AnActionEvent e) {
final Project project = e.getData(PlatformDataKeys.PROJECT);
if (project != null) {
@@ -31,6 +31,7 @@ import com.intellij.openapi.vcs.update.UpdatedFiles;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ui.UIUtil;
import git4idea.GitRevisionNumber;
import git4idea.GitVcs;
import git4idea.actions.GitRepositoryAction;
@@ -141,10 +142,15 @@ public class GitMergeUtil {
}
action.delayTask(new TransactionRunnable() {
public void run(List<VcsException> exceptionList) {
ProjectLevelVcsManagerEx manager = (ProjectLevelVcsManagerEx)ProjectLevelVcsManager.getInstance(project);
UpdateInfoTree tree = manager.showUpdateProjectInfo(files, actionName, actionInfo, false);
tree.setBefore(beforeLabel);
tree.setAfter(LocalHistory.getInstance().putSystemLabel(project, "After update"));
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
ProjectLevelVcsManagerEx manager = (ProjectLevelVcsManagerEx)ProjectLevelVcsManager.getInstance(project);
UpdateInfoTree tree = manager.showUpdateProjectInfo(files, actionName, actionInfo, false);
tree.setBefore(beforeLabel);
tree.setAfter(LocalHistory.getInstance().putSystemLabel(project, "After update"));
}
});
}
});
final Collection<String> unmergedNames = files.getGroupById(FileGroup.MERGED_WITH_CONFLICT_ID).getFiles();
@@ -159,7 +165,15 @@ public class GitMergeUtil {
unmerged.add(f);
}
}
AbstractVcsHelper.getInstance(project).showMergeDialog(unmerged, GitVcs.getInstance(project).getMergeProvider());
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
GitVcs vcs = GitVcs.getInstance(project);
if (vcs != null) {
AbstractVcsHelper.getInstance(project).showMergeDialog(unmerged, vcs.getMergeProvider());
}
}
});
}
});
}