From af5a1460fefd9b66a6bdc5fcb0bec1eed645b70b Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Sun, 21 Jun 2015 18:49:56 +0300 Subject: [PATCH] [vcs] get rid of Continuation in PatchApplier, shelve and GitUpdateProcess Substitute it with a more clear control flow. * PatchApplier: make ApplyPatchTask synchronous: it is executed from the EDT, so update the ChangeListManager in SYNCHRONOUS mode (modal task). * ShelveChangesManager: make unshelveChangeList synchronous as well, surround the part which needs to be called from the EDT by invokeAndWait. * GitUpdateProcess: substitute GitComplexProcess (which is continuation-based) with GitFreezingProcess (which does the same about blocking and freezing, but without the continuation logic). * GitStashChangesSaver#load doesn't actually throw a VcsException => remove --- .../diff/impl/patch/formove/PatchApplier.java | 52 ++------ .../patch/ApplyPatchDefaultExecutor.java | 2 + .../patch/ApplyPatchDifferentiatedDialog.java | 2 + .../changes/shelf/ShelveChangesManager.java | 115 ++++++++---------- .../src/git4idea/stash/GitChangesSaver.java | 8 +- .../git4idea/stash/GitShelveChangesSaver.java | 6 +- .../src/git4idea/stash/GitShelveUtils.java | 60 +++------ .../git4idea/stash/GitStashChangesSaver.java | 14 +-- .../src/git4idea/update/GitUpdateProcess.java | 51 ++------ .../git4idea/util/GitPreservingProcess.java | 10 +- .../treeConflict/MergeFromTheirsResolver.java | 2 +- 11 files changed, 108 insertions(+), 214 deletions(-) diff --git a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/patch/formove/PatchApplier.java b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/patch/formove/PatchApplier.java index 01cf402f6ade..a795b6ce5f40 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/diff/impl/patch/formove/PatchApplier.java +++ b/platform/vcs-impl/src/com/intellij/openapi/diff/impl/patch/formove/PatchApplier.java @@ -26,7 +26,6 @@ import com.intellij.openapi.diff.impl.patch.apply.ApplyTextFilePatch; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.FileTypes; import com.intellij.openapi.fileTypes.ex.FileTypeChooser; -import com.intellij.openapi.progress.AsynchronousExecution; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.ui.Messages; @@ -43,11 +42,10 @@ import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.Consumer; import com.intellij.util.WaitForProgressToShow; -import com.intellij.util.continuation.*; import com.intellij.vcsUtil.VcsUtil; +import org.jetbrains.annotations.CalledInAwt; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.CalledInAwt; import java.io.IOException; import java.util.*; @@ -127,23 +125,12 @@ public class PatchApplier { return new FilesMover(clm, targetChangeList); } - @AsynchronousExecution + @CalledInAwt public void execute() { - execute(true); + execute(true, false); } - @AsynchronousExecution - public void execute(boolean showSuccessNotification) { - final Continuation continuation = ApplicationManager.getApplication().isDispatchThread() ? - Continuation.createFragmented(myProject, true) : - Continuation.createForCurrentProgress(myProject, true); - final GatheringContinuationContext initContext = - new GatheringContinuationContext(); - scheduleSelf(showSuccessNotification, initContext, false); - continuation.run(initContext.getList()); - } - - public class ApplyPatchTask extends TaskDescriptor { + public class ApplyPatchTask { private ApplyPatchStatus myStatus; private final boolean myShowNotification; private final boolean mySystemOperation; @@ -151,14 +138,12 @@ public class PatchApplier { private VcsShowConfirmationOption.Value myDeleteconfirmationvalue; public ApplyPatchTask(final boolean showNotification, boolean systemOperation) { - super("", Where.AWT); myShowNotification = showNotification; mySystemOperation = systemOperation; } @CalledInAwt - @Override - public void run(ContinuationContext context) { + public void run() { myRemainingPatches.addAll(myPatches); final ApplyPatchStatus patchStatus = nonWriteActionPreCheck(); @@ -179,7 +164,7 @@ public class PatchApplier { if(myShowNotification || !ApplyPatchStatus.SUCCESS.equals(myStatus)) { showApplyStatus(myProject, myStatus); } - refreshFiles(trigger.getAffected(), context); + refreshFiles(trigger.getAffected()); } @CalledInAwt @@ -240,9 +225,9 @@ public class PatchApplier { return new ApplyPatchTask(showSuccessNotification, silentAddDelete); } - @AsynchronousExecution - public void scheduleSelf(boolean showSuccessNotification, @NotNull final ContinuationContext context, boolean silentAddDelete) { - context.next(createApplyPart(showSuccessNotification, silentAddDelete)); + @CalledInAwt + public void execute(boolean showSuccessNotification, boolean silentAddDelete) { + createApplyPart(showSuccessNotification, silentAddDelete).run(); } @CalledInAwt @@ -289,7 +274,7 @@ public class PatchApplier { } directlyAffected.addAll(trigger.getAffected()); final Consumer> mover = localChangeList == null ? null : createMover(project, localChangeList); - refreshPassedFilesAndMoveToChangelist(project, null, directlyAffected, indirectlyAffected, mover); + refreshPassedFilesAndMoveToChangelist(project, directlyAffected, indirectlyAffected, mover); showApplyStatus(project, result); return result; } @@ -347,12 +332,12 @@ public class PatchApplier { } @CalledInAwt - protected void refreshFiles(final Collection additionalDirectly, @Nullable final ContinuationContext context) { + protected void refreshFiles(final Collection additionalDirectly) { final List directlyAffected = myVerifier.getDirectlyAffected(); final List indirectlyAffected = myVerifier.getAllAffected(); directlyAffected.addAll(additionalDirectly); - refreshPassedFilesAndMoveToChangelist(myProject, context, directlyAffected, indirectlyAffected, myToTargetListsMover); + refreshPassedFilesAndMoveToChangelist(myProject, directlyAffected, indirectlyAffected, myToTargetListsMover); } public List getDirectlyAffected() { @@ -365,14 +350,9 @@ public class PatchApplier { @CalledInAwt public static void refreshPassedFilesAndMoveToChangelist(@NotNull final Project project, - final ContinuationContext context, final Collection directlyAffected, final Collection indirectlyAffected, final Consumer> targetChangelistMover) { - if (context != null) { - context.suspend(); - } - final LocalFileSystem lfs = LocalFileSystem.getInstance(); for (FilePath filePath : directlyAffected) { lfs.refreshAndFindFileByIoFile(filePath.getIOFile()); @@ -386,11 +366,8 @@ public class PatchApplier { @Override public void run() { targetChangelistMover.consume(directlyAffected); - if (context != null) { - context.ping(); - } } - }, InvokeAfterUpdateMode.BACKGROUND_CANCELLABLE, + }, InvokeAfterUpdateMode.SYNCHRONOUS_CANCELLABLE, VcsBundle.message("change.lists.manager.move.changes.to.list"), new Consumer() { @Override @@ -400,9 +377,6 @@ public class PatchApplier { }, null); } else { markDirty(VcsDirtyScopeManager.getInstance(project), directlyAffected, indirectlyAffected); - if (context != null) { - context.ping(); - } } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchDefaultExecutor.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchDefaultExecutor.java index 7df56d21c58e..198e4ad24e6c 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchDefaultExecutor.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchDefaultExecutor.java @@ -33,6 +33,7 @@ import com.intellij.util.Consumer; import com.intellij.util.containers.Convertor; import com.intellij.util.containers.HashSet; import com.intellij.util.containers.MultiMap; +import org.jetbrains.annotations.CalledInAwt; import java.util.Collection; import java.util.LinkedList; @@ -52,6 +53,7 @@ public class ApplyPatchDefaultExecutor implements ApplyPatchExecutor patchGroups, LocalChangeList localList, diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchDifferentiatedDialog.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchDifferentiatedDialog.java index 2b65a17cf598..e25bb0ba826f 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchDifferentiatedDialog.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/ApplyPatchDifferentiatedDialog.java @@ -55,6 +55,7 @@ import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.Convertor; import com.intellij.util.containers.MultiMap; import com.intellij.util.ui.UIUtil; +import org.jetbrains.annotations.CalledInAwt; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -287,6 +288,7 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper { return actions.toArray(new Action[actions.size()]); } + @CalledInAwt private void runExecutor(ApplyPatchExecutor executor) { final Collection included = getIncluded(); if (included.isEmpty()) return; diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManager.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManager.java index d40688d3fe70..577e8f488169 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManager.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/shelf/ShelveChangesManager.java @@ -25,6 +25,7 @@ package com.intellij.openapi.vcs.changes.shelf; import com.intellij.ide.impl.ProjectUtil; import com.intellij.lifecycle.PeriodicalTasksCloser; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.application.impl.LaterInvocator; import com.intellij.openapi.components.AbstractProjectComponent; @@ -33,7 +34,6 @@ import com.intellij.openapi.diff.impl.patch.*; import com.intellij.openapi.diff.impl.patch.apply.ApplyFilePatchBase; import com.intellij.openapi.diff.impl.patch.formove.CustomBinaryPatchApplier; import com.intellij.openapi.diff.impl.patch.formove.PatchApplier; -import com.intellij.openapi.progress.AsynchronousExecution; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; @@ -52,13 +52,13 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.Consumer; import com.intellij.util.PathUtil; import com.intellij.util.SmartList; -import com.intellij.util.continuation.*; import com.intellij.util.messages.MessageBus; import com.intellij.util.messages.Topic; import com.intellij.util.text.CharArrayCharSequence; import com.intellij.util.ui.UIUtil; import com.intellij.vcsUtil.FilesProgress; import org.jdom.Element; +import org.jetbrains.annotations.CalledInAny; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -355,60 +355,55 @@ public class ShelveChangesManager extends AbstractProjectComponent implements JD } } - @AsynchronousExecution + @CalledInAny public void unshelveChangeList(final ShelvedChangeList changeList, @Nullable final List changes, @Nullable final List binaryFiles, @Nullable final LocalChangeList targetChangeList, boolean showSuccessNotification) { - final Continuation continuation = Continuation.createForCurrentProgress(myProject, true); - final GatheringContinuationContext initContext = new GatheringContinuationContext(); - scheduleUnshelveChangeList(changeList, changes, binaryFiles, targetChangeList, showSuccessNotification, initContext, false, - false, null, null); - continuation.run(initContext.getList()); + unshelveChangeList(changeList, changes, binaryFiles, targetChangeList, showSuccessNotification, false, false, null, null); } - @AsynchronousExecution - public void scheduleUnshelveChangeList(final ShelvedChangeList changeList, - @Nullable final List changes, - @Nullable final List binaryFiles, - @Nullable final LocalChangeList targetChangeList, - final boolean showSuccessNotification, - final ContinuationContext context, - final boolean systemOperation, - final boolean reverse, - final String leftConflictTitle, - final String rightConflictTitle) { - context.next(new TaskDescriptor("", Where.AWT) { + @CalledInAny + public void unshelveChangeList(final ShelvedChangeList changeList, + @Nullable final List changes, + @Nullable final List binaryFiles, + @Nullable final LocalChangeList targetChangeList, + final boolean showSuccessNotification, + final boolean systemOperation, + final boolean reverse, + final String leftConflictTitle, + final String rightConflictTitle) { + final List remainingPatches = new ArrayList(); + + final CommitContext commitContext = new CommitContext(); + final List textFilePatches; + try { + textFilePatches = loadTextPatches(myProject, changeList, changes, remainingPatches, commitContext); + } + catch (IOException e) { + LOG.info(e); + PatchApplier.showError(myProject, "Cannot load patch(es): " + e.getMessage(), true); + return; + } + catch (PatchSyntaxException e) { + PatchApplier.showError(myProject, "Cannot load patch(es): " + e.getMessage(), true); + LOG.info(e); + return; + } + + final List patches = new ArrayList(textFilePatches); + + final List remainingBinaries = new ArrayList(); + final List binaryFilesToUnshelve = getBinaryFilesToUnshelve(changeList, binaryFiles, remainingBinaries); + + for (final ShelvedBinaryFile shelvedBinaryFile : binaryFilesToUnshelve) { + patches.add(new ShelvedBinaryFilePatch(shelvedBinaryFile)); + } + + ApplicationManager.getApplication().invokeAndWait(new Runnable() { @Override - public void run(ContinuationContext contextInner) { - final List remainingPatches = new ArrayList(); - - final CommitContext commitContext = new CommitContext(); - final List textFilePatches; - try { - textFilePatches = loadTextPatches(myProject, changeList, changes, remainingPatches, commitContext); - } - catch (IOException e) { - LOG.info(e); - PatchApplier.showError(myProject, "Cannot load patch(es): " + e.getMessage(), true); - return; - } - catch (PatchSyntaxException e) { - PatchApplier.showError(myProject, "Cannot load patch(es): " + e.getMessage(), true); - LOG.info(e); - return; - } - - final List patches = new ArrayList(textFilePatches); - - final List remainingBinaries = new ArrayList(); - final List binaryFilesToUnshelve = getBinaryFilesToUnshelve(changeList, binaryFiles, remainingBinaries); - - for (final ShelvedBinaryFile shelvedBinaryFile : binaryFilesToUnshelve) { - patches.add(new ShelvedBinaryFilePatch(shelvedBinaryFile)); - } - + public void run() { final BinaryPatchApplier binaryPatchApplier = new BinaryPatchApplier(); final PatchApplier patchApplier = new PatchApplier(myProject, myProject.getBaseDir(), @@ -416,24 +411,18 @@ public class ShelveChangesManager extends AbstractProjectComponent implements JD rightConflictTitle); patchApplier.setIsSystemOperation(systemOperation); - // after patch applier part - contextInner.next(new TaskDescriptor("", Where.AWT) { - @Override - public void run(ContinuationContext context) { - remainingPatches.addAll(patchApplier.getRemainingPatches()); + remainingPatches.addAll(patchApplier.getRemainingPatches()); - if (remainingPatches.isEmpty() && remainingBinaries.isEmpty()) { - recycleChangeList(changeList); - } - else { - saveRemainingPatches(changeList, remainingPatches, remainingBinaries, commitContext); - } - } - }); + if (remainingPatches.isEmpty() && remainingBinaries.isEmpty()) { + recycleChangeList(changeList); + } + else { + saveRemainingPatches(changeList, remainingPatches, remainingBinaries, commitContext); + } - patchApplier.scheduleSelf(showSuccessNotification, contextInner, systemOperation); + patchApplier.execute(showSuccessNotification, systemOperation); } - }); + }, ModalityState.defaultModalityState()); } private static List loadTextPatches(final Project project, diff --git a/plugins/git4idea/src/git4idea/stash/GitChangesSaver.java b/plugins/git4idea/src/git4idea/stash/GitChangesSaver.java index a09c771f842e..d4849e5065eb 100644 --- a/plugins/git4idea/src/git4idea/stash/GitChangesSaver.java +++ b/plugins/git4idea/src/git4idea/stash/GitChangesSaver.java @@ -24,7 +24,6 @@ import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vcs.VcsNotifier; import com.intellij.openapi.vcs.changes.ChangeListManagerEx; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.util.continuation.ContinuationContext; import git4idea.GitPlatformFacade; import git4idea.commands.Git; import git4idea.config.GitVcsSettings; @@ -108,8 +107,8 @@ public abstract class GitChangesSaver { * Loads local changes from stash or shelf, and sorts the changes back to the change lists they were before update. * @param context */ - public void restoreLocalChanges(ContinuationContext context) { - load(context); + public void restoreLocalChanges() { + load(); } public void notifyLocalChangesAreNotRestored() { @@ -138,9 +137,8 @@ public abstract class GitChangesSaver { /** * Loads the changes - specific for chosen save strategy. - * @param exceptionConsumer */ - protected abstract void load(ContinuationContext exceptionConsumer); + public abstract void load(); /** * @return true if there were local changes to save. diff --git a/plugins/git4idea/src/git4idea/stash/GitShelveChangesSaver.java b/plugins/git4idea/src/git4idea/stash/GitShelveChangesSaver.java index 9d6d4ae684f9..812df757cb30 100644 --- a/plugins/git4idea/src/git4idea/stash/GitShelveChangesSaver.java +++ b/plugins/git4idea/src/git4idea/stash/GitShelveChangesSaver.java @@ -25,7 +25,6 @@ import com.intellij.openapi.vcs.changes.shelf.ShelvedChangeList; import com.intellij.openapi.vcs.changes.shelf.ShelvedChangesViewManager; import com.intellij.openapi.vcs.impl.LocalChangesUnderRoots; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.util.continuation.ContinuationContext; import git4idea.GitPlatformFacade; import git4idea.commands.Git; import git4idea.i18n.GitBundle; @@ -85,13 +84,14 @@ public class GitShelveChangesSaver extends GitChangesSaver { myProgressIndicator.setText(oldProgressTitle); } - protected void load(ContinuationContext context) { + @Override + public void load() { if (myShelvedLists != null) { LOG.info("load "); String oldProgressTitle = myProgressIndicator.getText(); myProgressIndicator.setText(GitBundle.getString("update.unshelving.changes")); for (ShelvedChangeList list : myShelvedLists.values()) { - GitShelveUtils.doSystemUnshelve(myProject, list, myShelveManager, context, + GitShelveUtils.doSystemUnshelve(myProject, list, myShelveManager, getConflictLeftPanelTitle(), getConflictRightPanelTitle()); } myProgressIndicator.setText(oldProgressTitle); diff --git a/plugins/git4idea/src/git4idea/stash/GitShelveUtils.java b/plugins/git4idea/src/git4idea/stash/GitShelveUtils.java index 78b901fead73..6ea04a00e5ed 100644 --- a/plugins/git4idea/src/git4idea/stash/GitShelveUtils.java +++ b/plugins/git4idea/src/git4idea/stash/GitShelveUtils.java @@ -20,7 +20,6 @@ import com.intellij.openapi.command.undo.DocumentReference; import com.intellij.openapi.command.undo.DocumentReferenceManager; import com.intellij.openapi.command.undo.UndoManager; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.progress.AsynchronousExecution; import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vcs.changes.Change; @@ -33,9 +32,6 @@ import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.Processor; import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.continuation.ContinuationContext; -import com.intellij.util.continuation.TaskDescriptor; -import com.intellij.util.continuation.Where; import org.jetbrains.annotations.CalledInAwt; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -47,53 +43,29 @@ import java.util.Collection; import java.util.HashSet; import java.util.List; -/** - * @author Kirill Likhodedov - */ public class GitShelveUtils { private static final Logger LOG = Logger.getInstance(GitShelveUtils.class.getName()); - /** - * Perform system level unshelve operation - * - * @param project the project - * @param shelvedChangeList the shelved change list - * @param shelveManager the shelve manager - */ - @AsynchronousExecution - public static void doSystemUnshelve(final Project project, final ShelvedChangeList shelvedChangeList, + public static void doSystemUnshelve(final Project project, + final ShelvedChangeList shelvedChangeList, final ShelveChangesManager shelveManager, - final @NotNull ContinuationContext context, - @Nullable final String leftConflictTitle, @Nullable final String rightConflictTitle) { + @Nullable final String leftConflictTitle, + @Nullable final String rightConflictTitle) { VirtualFile baseDir = project.getBaseDir(); assert baseDir != null; final String projectPath = baseDir.getPath() + "/"; - final List changes = shelvedChangeList.getChanges(project); - context.next(new TaskDescriptor("Refreshing files before unshelve", Where.POOLED) { - @Override - public void run(ContinuationContext context) { - LOG.info("doSystemUnshelve "); - // The changes are temporary copied to the first local change list, the next operation will restore them back - // Refresh files that might be affected by unshelve - refreshFilesBeforeUnshelve(project, shelvedChangeList, projectPath); - LOG.info("doSystemUnshelve files refreshed. unshelving in AWT thread."); - } - }, new TaskDescriptor("", Where.AWT) { - @Override - public void run(ContinuationContext context) { - LOG.info("Unshelving in UI thread. shelvedChangeList: " + shelvedChangeList); - // we pass null as target change list for Patch Applier to do NOTHING with change lists - shelveManager.scheduleUnshelveChangeList(shelvedChangeList, changes, - shelvedChangeList.getBinaryFiles(), null, false, context, true, - true, leftConflictTitle, rightConflictTitle); - } - }, new TaskDescriptor("", Where.AWT) { - @Override - public void run(ContinuationContext context) { - markUnshelvedFilesNonUndoable(project, changes); - } - }); + LOG.info("refreshing files "); + // The changes are temporary copied to the first local change list, the next operation will restore them back + // Refresh files that might be affected by unshelve + refreshFilesBeforeUnshelve(project, shelvedChangeList, projectPath); + + LOG.info("Unshelving shelvedChangeList: " + shelvedChangeList); + // we pass null as target change list for Patch Applier to do NOTHING with change lists + List changes = shelvedChangeList.getChanges(project); + shelveManager.unshelveChangeList(shelvedChangeList, changes, shelvedChangeList.getBinaryFiles(), null, false, true, + true, leftConflictTitle, rightConflictTitle); + markUnshelvedFilesNonUndoable(project, changes); } @CalledInAwt @@ -116,7 +88,7 @@ public class GitShelveUtils { } } - public static void refreshFilesBeforeUnshelve(final Project project, ShelvedChangeList shelvedChangeList, String projectPath) { + private static void refreshFilesBeforeUnshelve(final Project project, ShelvedChangeList shelvedChangeList, String projectPath) { HashSet filesToRefresh = new HashSet(); for (ShelvedChange c : shelvedChangeList.getChanges(project)) { if (c.getBeforePath() != null) { diff --git a/plugins/git4idea/src/git4idea/stash/GitStashChangesSaver.java b/plugins/git4idea/src/git4idea/stash/GitStashChangesSaver.java index 8e20a67fceab..55f348944bcc 100644 --- a/plugins/git4idea/src/git4idea/stash/GitStashChangesSaver.java +++ b/plugins/git4idea/src/git4idea/stash/GitStashChangesSaver.java @@ -28,7 +28,6 @@ import com.intellij.openapi.vcs.impl.LocalChangesUnderRoots; import com.intellij.openapi.vcs.merge.MergeDialogCustomizer; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.util.continuation.ContinuationContext; import git4idea.GitPlatformFacade; import git4idea.commands.Git; import git4idea.commands.GitCommandResult; @@ -69,16 +68,7 @@ public class GitStashChangesSaver extends GitChangesSaver { } @Override - protected void load(@NotNull ContinuationContext context) { - try { - load(); - } - catch (VcsException e) { - context.handleException(e, false); - } - } - - public void load() throws VcsException { + public void load() { for (VirtualFile root : myStashedRoots) { loadRoot(root); } @@ -129,7 +119,7 @@ public class GitStashChangesSaver extends GitChangesSaver { * Returns true if the root was loaded with conflict. * False is returned in all other cases: in the case of success and in case of some other error. */ - private boolean loadRoot(final VirtualFile root) throws VcsException { + private boolean loadRoot(final VirtualFile root) { LOG.info("loadRoot " + root); myProgressIndicator.setText(GitHandlerUtil.formatOperationName("Unstashing changes to", root)); diff --git a/plugins/git4idea/src/git4idea/update/GitUpdateProcess.java b/plugins/git4idea/src/git4idea/update/GitUpdateProcess.java index ff49a71255c6..d1a3d543f68e 100644 --- a/plugins/git4idea/src/git4idea/update/GitUpdateProcess.java +++ b/plugins/git4idea/src/git4idea/update/GitUpdateProcess.java @@ -30,14 +30,9 @@ import com.intellij.openapi.vcs.changes.ChangeListManager; import com.intellij.openapi.vcs.impl.LocalChangesUnderRoots; import com.intellij.openapi.vcs.update.UpdatedFiles; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.util.Consumer; import com.intellij.util.Function; import com.intellij.util.ObjectUtils; import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.continuation.ContinuationContext; -import com.intellij.util.continuation.ContinuationFinalTasksInserter; -import com.intellij.util.continuation.TaskDescriptor; -import com.intellij.util.continuation.Where; import com.intellij.util.text.DateFormatUtil; import git4idea.GitLocalBranch; import git4idea.GitPlatformFacade; @@ -54,12 +49,12 @@ import git4idea.rebase.GitRebaser; import git4idea.repo.GitBranchTrackInfo; import git4idea.repo.GitRepository; import git4idea.stash.GitChangesSaver; +import git4idea.util.GitFreezingProcess; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Collection; import java.util.HashMap; -import java.util.HashSet; import java.util.Map; import static git4idea.util.GitUIUtil.*; @@ -74,6 +69,7 @@ public class GitUpdateProcess { @NotNull private final Project myProject; @NotNull private final Git myGit; + @NotNull private final GitPlatformFacade myPlatformFacade; @NotNull private final Collection myRepositories; private final boolean myCheckRebaseOverMergeProblem; private final UpdatedFiles myUpdatedFiles; @@ -83,7 +79,6 @@ public class GitUpdateProcess { private final Map myTrackedBranches = new HashMap(); private GitUpdateResult myResult; - private final Collection myRootsToSave; public GitUpdateProcess(@NotNull Project project, @NotNull GitPlatformFacade platformFacade, @@ -92,6 +87,7 @@ public class GitUpdateProcess { @NotNull UpdatedFiles updatedFiles, boolean checkRebaseOverMergeProblem) { myProject = project; + myPlatformFacade = platformFacade; myRepositories = repositories; myCheckRebaseOverMergeProblem = checkRebaseOverMergeProblem; myGit = ServiceManager.getService(Git.class); @@ -136,26 +132,23 @@ public class GitUpdateProcess { if (!fetchAndNotify()) { return GitUpdateResult.NOT_READY; } - - GitComplexProcess.Operation updateOperation = new GitComplexProcess.Operation() { - @Override public void run(ContinuationContext continuationContext) { + new GitFreezingProcess(myProject, myPlatformFacade, "update", new Runnable() { + public void run() { AccessToken token = DvcsUtil.workingTreeChangeStarted(myProject); try { - myResult = updateImpl(updateMethod, continuationContext); + myResult = updateImpl(updateMethod); } finally { DvcsUtil.workingTreeChangeFinished(myProject, token); } } - }; - GitComplexProcess.execute(myProject, "update", updateOperation); - + }).execute(); myProgressIndicator.setText(oldText); return myResult; } @NotNull - private GitUpdateResult updateImpl(@NotNull UpdateMethod updateMethod, ContinuationContext context) { + private GitUpdateResult updateImpl(@NotNull UpdateMethod updateMethod) { Map updaters; try { updaters = defineUpdaters(updateMethod); @@ -193,6 +186,7 @@ public class GitUpdateProcess { } // save local changes if needed (update via merge may perform without saving). + Collection myRootsToSave = ContainerUtil.newArrayList(); LOG.info("updateImpl: identifying if save is needed..."); for (Map.Entry entry : updaters.entrySet()) { VirtualFile root = entry.getKey(); @@ -244,7 +238,7 @@ public class GitUpdateProcess { } else { LOG.info("updateImpl: restoring local changes..."); - restoreLocalChanges(context); + restoreLocalChanges(); } } return compoundResult; @@ -312,28 +306,9 @@ public class GitUpdateProcess { return compoundResult.join(result); } - private void restoreLocalChanges(ContinuationContext context) { - context.addExceptionHandler(VcsException.class, new Consumer() { - @Override - public void consume(VcsException e) { - LOG.info("Couldn't restore local changes after update", e); - notifyImportantError(myProject, "Couldn't restore local changes after update", - "Restoring changes saved before update failed with an error.
" + e.getLocalizedMessage()); - } - }); - // try restore changes under all circumstances - final ContinuationFinalTasksInserter finalTasksInserter = new ContinuationFinalTasksInserter(context); - finalTasksInserter.allNextAreFinal(); - // !!!! this task is put NEXT, i.e. if unshelve/unstash will be done synchronously or scheduled on context, - // it is unimportant -> files will be refreshed after - context.next(new TaskDescriptor("Refresh local files", Where.POOLED) { - @Override - public void run(ContinuationContext context) { - mySaver.refresh(); - } - }); - mySaver.restoreLocalChanges(context); - finalTasksInserter.removeFinalPropertyAdder(); + private void restoreLocalChanges() { + mySaver.restoreLocalChanges(); + mySaver.refresh(); } // fetch all roots. If an error happens, return false and notify about errors. diff --git a/plugins/git4idea/src/git4idea/util/GitPreservingProcess.java b/plugins/git4idea/src/git4idea/util/GitPreservingProcess.java index 1c3da9f353b7..1b1da5b932b3 100644 --- a/plugins/git4idea/src/git4idea/util/GitPreservingProcess.java +++ b/plugins/git4idea/src/git4idea/util/GitPreservingProcess.java @@ -167,15 +167,7 @@ public class GitPreservingProcess { public void load() { if (myLoaded.compareAndSet(false, true)) { - try { - mySaver.load(); - } - catch (VcsException e) { - LOG.info("Couldn't load local changes", e); - VcsNotifier.getInstance(myProject).notifyError("Couldn't restore uncommitted changes", - String.format("Tried to unstash uncommitted changes, but failed with error.
%s", - join(e.getMessages()))); - } + mySaver.load(); } else { LOG.warn("The changes were already loaded", new Throwable()); diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/treeConflict/MergeFromTheirsResolver.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/treeConflict/MergeFromTheirsResolver.java index 15630e188a25..5f242fa5b5a4 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/treeConflict/MergeFromTheirsResolver.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/treeConflict/MergeFromTheirsResolver.java @@ -256,7 +256,7 @@ public class MergeFromTheirsResolver { final PatchApplier patchApplier = new PatchApplier(myVcs.getProject(), myBaseDir, patches, localList, null, null); - patchApplier.scheduleSelf(false, myInner, true); // 3 + patchApplier.execute(false, true); // 3 boolean thereAreCreations = false; for (FilePatch patch : patches) { if (patch.isNewFile() || ! Comparing.equal(patch.getAfterName(), patch.getBeforeName())) {