GitTask: ability to run without creating a Task; use this in git update.
authorKirill Likhodedov <kirill.likhodedov@jetbrains.com>
Mon, 4 Apr 2011 13:26:09 +0000 (17:26 +0400)
committerKirill Likhodedov <kirill.likhodedov@jetbrains.com>
Mon, 4 Apr 2011 13:26:09 +0000 (17:26 +0400)
1. GitTask#setProgressIndicator => background task will be started in the current thread or on a pooled thread (if current is EDT).
 2. GitTask#myExecuteProgressInAwt is not needed anymore. Just don't execute time consuming tasks in the result handling methods.
 3. Git Update (fetch, merge, rebase, stash, unstash) use existing progress indicator; progress indicator message is preserved and then restored.

plugins/git4idea/src/git4idea/commands/GitTask.java
plugins/git4idea/src/git4idea/rebase/GitRebaser.java
plugins/git4idea/src/git4idea/update/GitFetcher.java
plugins/git4idea/src/git4idea/update/GitMergeUpdater.java
plugins/git4idea/src/git4idea/update/GitRebaseUpdater.java
plugins/git4idea/src/git4idea/update/GitShelveChangesSaver.java
plugins/git4idea/src/git4idea/update/GitStashChangesSaver.java
plugins/git4idea/src/git4idea/update/GitUpdateProcess.java

index d29fcbff009bf40fce7aa70eb5f41cd8a412799f..aeee1251d30065982173d4e7b8e8b3845e9ffde6 100644 (file)
@@ -26,7 +26,6 @@ import com.intellij.openapi.util.Disposer;
 import com.intellij.openapi.util.Key;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.vcs.VcsException;
-import com.intellij.util.ui.UIUtil;
 import git4idea.GitVcs;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -60,7 +59,7 @@ public class GitTask {
   private final GitHandler myHandler;
   private final String myTitle;
   private GitProgressAnalyzer myProgressAnalyzer;
-  private boolean myExecuteResultInAwt = true;
+  private ProgressIndicator myProgressIndicator;
 
   public GitTask(Project project, GitHandler handler, String title) {
     myProject = project;
@@ -134,7 +133,7 @@ public class GitTask {
       };
       ProgressManager.getInstance().run(task);
     } else {
-      BackgroundableTask task = new BackgroundableTask(myProject, myHandler, myTitle) {
+      final BackgroundableTask task = new BackgroundableTask(myProject, myHandler, myTitle) {
         @Override public void onSuccess() {
           commonOnSuccess(LOCK, resultHandler);
           completed.set(true);
@@ -144,7 +143,11 @@ public class GitTask {
           completed.set(true);
         }
       };
-      GitVcs.runInBackground(task);
+      if (myProgressIndicator == null) {
+        GitVcs.runInBackground(task);
+      } else {
+        task.runAlone();
+      }
     }
 
     if (sync) {
@@ -161,37 +164,17 @@ public class GitTask {
   }
 
   private void commonOnSuccess(final Object LOCK, final GitTaskResultHandler resultHandler) {
-    final Runnable successRunnable = new Runnable() {
-      @Override public void run() {
-        GitTaskResult res = !myHandler.errors().isEmpty() ? GitTaskResult.GIT_ERROR : GitTaskResult.OK;
-        resultHandler.run(res);
-        synchronized (LOCK) {
-          LOCK.notifyAll();
-        }
-      }
-    };
-    executeInProperThread(successRunnable);
+    GitTaskResult res = !myHandler.errors().isEmpty() ? GitTaskResult.GIT_ERROR : GitTaskResult.OK;
+    resultHandler.run(res);
+    synchronized (LOCK) {
+      LOCK.notifyAll();
+    }
   }
 
   private void commonOnCancel(final Object LOCK, final GitTaskResultHandler resultHandler) {
-    final Runnable cancelRunnable = new Runnable() {
-      @Override
-      public void run() {
-        resultHandler.run(GitTaskResult.CANCELLED);
-        synchronized (LOCK) {
-          LOCK.notifyAll();
-        }
-      }
-    };
-    executeInProperThread(cancelRunnable);
-  }
-
-  // executes on a pooled thread or on AWT thread depending on the setting.
-  private void executeInProperThread(Runnable runnable) {
-    if (myExecuteResultInAwt) {
-      UIUtil.invokeAndWaitIfNeeded(runnable);
-    } else {
-      ApplicationManager.getApplication().executeOnPooledThread(runnable);
+    resultHandler.run(GitTaskResult.CANCELLED);
+    synchronized (LOCK) {
+      LOCK.notifyAll();
     }
   }
 
@@ -258,8 +241,8 @@ public class GitTask {
     myProgressAnalyzer = progressAnalyzer;
   }
 
-  public void setExecuteResultInAwt(boolean executeResultInAwt) {
-    myExecuteResultInAwt = executeResultInAwt;
+  public void setProgressIndicator(ProgressIndicator progressIndicator) {
+    myProgressIndicator = progressIndicator;
   }
 
   /**
@@ -288,6 +271,31 @@ public class GitTask {
       myDelegate.run(indicator);
     }
 
+    public final void runAlone() {
+      if (ApplicationManager.getApplication().isDispatchThread()) {
+        ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
+          @Override
+          public void run() {
+            justRun();
+          }
+        });
+      } else {
+        justRun();
+      }
+    }
+
+    private void justRun() {
+      String oldTitle = myProgressIndicator.getText();
+      myProgressIndicator.setText(myTitle);
+      myDelegate.run(myProgressIndicator);
+      myProgressIndicator.setText(oldTitle);
+      if (myProgressIndicator.isCanceled()) {
+        onCancel();
+      } else {
+        onSuccess();
+      }
+    }
+
     @Override
     public void execute(ProgressIndicator indicator) {
       addListeners(this, indicator);
index c348a310dfed3a6a9e848664c63ed93235bfa459..9d968296964043c33193403676f46c5f04502fec 100644 (file)
@@ -84,7 +84,6 @@ public class GitRebaser {
     rh.addLineListener(rebaseConflictDetector);
 
     final GitTask rebaseTask = new GitTask(myProject, rh, "git rebase " + startOperation);
-    rebaseTask.setExecuteResultInAwt(false);
     rebaseTask.setProgressAnalyzer(new GitStandardProgressAnalyzer());
     return executeRebaseTaskInBackground(root, rh, rebaseConflictDetector, rebaseTask);
   }
@@ -131,7 +130,6 @@ public class GitRebaser {
       rebaseEditorService.configureHandler(h, rebaseEditorNo);
 
       final GitTask rebaseTask = new GitTask(myProject, h, "Reordering commits");
-      rebaseTask.setExecuteResultInAwt(false);
       return executeRebaseTaskInBackground(root, h, rebaseConflictDetector, rebaseTask);
     } finally {
       // unregistering rebase service
index 8122815aca3b7ee1fb543e1abb76513ec0208a0a..3fdd5c294d5302ef13905ced9445ad603976408f 100644 (file)
@@ -16,6 +16,7 @@
 package git4idea.update;
 
 import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.progress.ProgressIndicator;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.vcs.VcsException;
 import com.intellij.openapi.vfs.VirtualFile;
@@ -32,10 +33,12 @@ public class GitFetcher {
 
   private static final Logger LOG = Logger.getInstance(GitFetcher.class);
   private final Project myProject;
+  private final ProgressIndicator myProgressIndicator;
   private final Collection<VcsException> myErrors = new HashSet<VcsException>();
 
-  public GitFetcher(Project project) {
+  public GitFetcher(Project project, ProgressIndicator progressIndicator) {
     myProject = project;
+    myProgressIndicator = progressIndicator;
   }
 
   /**
@@ -47,6 +50,7 @@ public class GitFetcher {
     final GitLineHandler h = new GitLineHandler(myProject, root, GitCommand.FETCH);
 
     final GitTask fetchTask = new GitTask(myProject, h, "Fetching changes...");
+    fetchTask.setProgressIndicator(myProgressIndicator);
     fetchTask.setProgressAnalyzer(new GitStandardProgressAnalyzer());
     final AtomicBoolean success = new AtomicBoolean();
     fetchTask.executeInBackground(true, new GitTaskResultHandlerAdapter() {
index 2f6c599ad1fddc0740f7f302bab143f969af9ede..8da692c716262e2d25808792d400d12cd94c698d 100644 (file)
@@ -73,8 +73,8 @@ public class GitMergeUpdater extends GitUpdater {
     final MergeLineListener mergeLineListener = new MergeLineListener();
     mergeHandler.addLineListener(mergeLineListener);
 
-    final GitTask mergeTask = new GitTask(myProject, mergeHandler, "git merge");
-    mergeTask.setExecuteResultInAwt(false);
+    final GitTask mergeTask = new GitTask(myProject, mergeHandler, "Merging changes");
+    mergeTask.setProgressIndicator(myProgressIndicator);
     mergeTask.setProgressAnalyzer(new GitStandardProgressAnalyzer());
     final AtomicReference<GitUpdateResult> updateResult = new AtomicReference<GitUpdateResult>();
     final AtomicBoolean failure = new AtomicBoolean();
index 0ff486b4f108a72724ff8437734693f5e501e106..eae8f961c5496aba20f1e0dda519a42917535342 100644 (file)
@@ -64,22 +64,25 @@ public class GitRebaseUpdater extends GitUpdater {
     final GitRebaseProblemDetector rebaseConflictDetector = new GitRebaseProblemDetector();
     rebaseHandler.addLineListener(rebaseConflictDetector);
 
-    GitTask pullTask = new GitTask(myProject, rebaseHandler, "git rebase");
-    pullTask.setExecuteResultInAwt(false);
-    pullTask.setProgressAnalyzer(new GitStandardProgressAnalyzer());
+    GitTask rebaseTask = new GitTask(myProject, rebaseHandler, "Rebasing");
+    rebaseTask.setProgressIndicator(myProgressIndicator);
+    rebaseTask.setProgressAnalyzer(new GitStandardProgressAnalyzer());
     final AtomicReference<GitUpdateResult> updateResult = new AtomicReference<GitUpdateResult>();
     final AtomicBoolean failure = new AtomicBoolean();
-    pullTask.executeInBackground(true, new GitTaskResultHandlerAdapter() {
-      @Override protected void onSuccess() {
+    rebaseTask.executeInBackground(true, new GitTaskResultHandlerAdapter() {
+      @Override
+      protected void onSuccess() {
         updateResult.set(GitUpdateResult.SUCCESS);
       }
 
-      @Override protected void onCancel() {
+      @Override
+      protected void onCancel() {
         cancel();
         updateResult.set(GitUpdateResult.CANCEL);
       }
 
-      @Override protected void onFailure() {
+      @Override
+      protected void onFailure() {
         failure.set(true);
       }
     });
index 3691a7c68677858bbc1660e90c6eb9c7ed6ee439..57000d3eebad5da65a145a25ee4baf826fc95ec6 100644 (file)
@@ -26,7 +26,6 @@ import com.intellij.openapi.vcs.changes.shelf.ShelveChangesManager;
 import com.intellij.openapi.vcs.changes.shelf.ShelvedChangeList;
 import com.intellij.openapi.vcs.changes.shelf.ShelvedChangesViewManager;
 import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.util.continuation.Continuation;
 import com.intellij.util.continuation.ContinuationContext;
 import git4idea.GitUtil;
 import git4idea.i18n.GitBundle;
@@ -60,9 +59,11 @@ public class GitShelveChangesSaver extends GitChangesSaver {
       changes.addAll(filterChangesByRoots(l.getChanges(), rootsToSave)); // adding only changes from roots which are to be saved
     }
     if (!changes.isEmpty()) {
+      String oldProgressTitle = myProgressIndicator.getText();
       myProgressIndicator.setText(GitBundle.getString("update.shelving.changes"));
       List<VcsException> exceptions = new ArrayList<VcsException>(1);
       myShelvedChangeList = GitStashUtils.shelveChanges(myProject, myShelveManager, changes, myStashMessage, exceptions);
+      myProgressIndicator.setText(oldProgressTitle);
       if (!exceptions.isEmpty()) {
         LOG.info("save " + exceptions, exceptions.get(0));
         throw exceptions.get(0);
@@ -73,10 +74,12 @@ public class GitShelveChangesSaver extends GitChangesSaver {
   protected void load(Runnable restoreListsRunnable, ContinuationContext context) {
     if (myShelvedChangeList != null) {
       LOG.info("load ");
+      String oldProgressTitle = myProgressIndicator.getText();
       myProgressIndicator.setText(GitBundle.getString("update.unshelving.changes"));
       if (myShelvedChangeList != null) {
         GitStashUtils.doSystemUnshelve(myProject, myShelvedChangeList, myShelveManager, restoreListsRunnable, context);
       }
+      myProgressIndicator.setText(oldProgressTitle);
     }
   }
 
index 7045a8d615bc4536da000163d8835b152f41049d..2d019bd9d5b6ff7576d1460e51dc035ff120ce5d 100644 (file)
@@ -114,10 +114,12 @@ public class GitStashChangesSaver extends GitChangesSaver {
     for (VirtualFile root : roots) {
       final String message = GitHandlerUtil.formatOperationName("Stashing changes from", root);
       LOG.info(message);
+      final String oldProgressTitle = myProgressIndicator.getText();
       myProgressIndicator.setText(message);
       if (GitStashUtils.saveStash(myProject, root, myStashMessage)) {
         myStashedRoots.add(root);
       }
+      myProgressIndicator.setText(oldProgressTitle);
     }
   }
 
@@ -150,8 +152,8 @@ public class GitStashChangesSaver extends GitChangesSaver {
       }
     });
 
-    final GitTask task = new GitTask(myProject, handler, "git stash pop");
-    task.setExecuteResultInAwt(false);
+    final GitTask task = new GitTask(myProject, handler, "Unstashing uncommitted changes");
+    task.setProgressIndicator(myProgressIndicator);
     final AtomicBoolean failure = new AtomicBoolean();
     task.executeInBackground(true, new GitTaskResultHandlerAdapter() {
       @Override protected void onSuccess() {
index e647da504b36afe917def1d954e13b416ff8c443..6ec253104ab63d0a825647aa5aa2e5b757bed060 100644 (file)
@@ -186,7 +186,7 @@ public class GitUpdateProcess {
 
   // fetch all roots. If an error happens, return false and notify about errors.
   private boolean fetchAndNotify() {
-    GitFetcher fetcher = new GitFetcher(myProject);
+    GitFetcher fetcher = new GitFetcher(myProject, myProgressIndicator);
     for (VirtualFile root : myRoots) {
       fetcher.fetch(root);
     }