diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ChangeHighlighterHolder.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ChangeHighlighterHolder.java index 3c445cc106c8..4dee367dfb7d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ChangeHighlighterHolder.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ChangeHighlighterHolder.java @@ -27,6 +27,7 @@ import com.intellij.openapi.editor.markup.TextAttributes; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.awt.*; import java.util.ArrayList; /** @@ -37,6 +38,7 @@ import java.util.ArrayList; class ChangeHighlighterHolder { private static final Logger LOG = Logger.getInstance(ChangeHighlighterHolder.class); + static final int APPLIED_CHANGE_TRANSPARENCY = 30; private Editor myEditor; private final ArrayList myHighlighters = new ArrayList(3); @@ -55,28 +57,41 @@ class ChangeHighlighterHolder { return myEditor.getMarkupModel(); } - private void highlighterCreated(RangeHighlighter highlighter, TextAttributes attrs) { + private void highlighterCreated(RangeHighlighter highlighter, TextAttributes attrs, boolean applied) { if (attrs != null) { - highlighter.setErrorStripeMarkColor(attrs.getErrorStripeColor()); + Color color = attrs.getErrorStripeColor(); + if (applied) { + color = makeColorForApplied(color); + } + highlighter.setErrorStripeMarkColor(color); } myHighlighters.add(highlighter); } + private static Color makeColorForApplied(Color color) { + return new Color(color.getRed(), color.getGreen(), color.getBlue(), APPLIED_CHANGE_TRANSPARENCY); + } + @Nullable - public RangeHighlighter addLineHighlighter(int line, int layer, TextDiffType diffType) { + public RangeHighlighter addLineHighlighter(int line, int layer, TextDiffType diffType, boolean applied) { if (myEditor.getDocument().getTextLength() == 0) return null; RangeHighlighter highlighter = getMarkupModel().addLineHighlighter(line, layer, null); highlighter.setLineSeparatorColor(diffType.getTextBackground(myEditor)); - highlighterCreated(highlighter, diffType.getTextAttributes(myEditor)); + highlighterCreated(highlighter, diffType.getTextAttributes(myEditor), applied); return highlighter; } @Nullable - public RangeHighlighter addRangeHighlighter(int start, int end, int layer, TextDiffType type, HighlighterTargetArea targetArea) { + public RangeHighlighter addRangeHighlighter(int start, + int end, + int layer, + TextDiffType type, + HighlighterTargetArea targetArea, + boolean applied) { if (getMarkupModel().getDocument().getTextLength() == 0) return null; TextAttributes attributes = type.getTextAttributes(myEditor); RangeHighlighter highlighter = getMarkupModel().addRangeHighlighter(start, end, layer, attributes, targetArea); - highlighterCreated(highlighter, attributes); + highlighterCreated(highlighter, attributes, applied); return highlighter; } diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ChangeType.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ChangeType.java index d53490ff22b3..49f2423b8dc6 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ChangeType.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ChangeType.java @@ -98,7 +98,7 @@ public class ChangeType { int length = text.length(); int start = changeSide.getStart(); int end = start + length; - RangeHighlighter highlighter = markup.addRangeHighlighter(start, end, LAYER, diffType, HighlighterTargetArea.EXACT_RANGE); + RangeHighlighter highlighter = markup.addRangeHighlighter(start, end, LAYER, diffType, HighlighterTargetArea.EXACT_RANGE, myApplied); if (highlighter != null) { highlighter.setLineSeparatorPlacement(SeparatorPlacement.TOP); @@ -111,7 +111,7 @@ public class ChangeType { end--; } - highlighter = markup.addRangeHighlighter(start, end, LAYER, TextDiffType.NONE, HighlighterTargetArea.EXACT_RANGE); + highlighter = markup.addRangeHighlighter(start, end, LAYER, TextDiffType.NONE, HighlighterTargetArea.EXACT_RANGE, myApplied); if (highlighter != null) { highlighter.setLineSeparatorPlacement(SeparatorPlacement.BOTTOM); highlighter.setLineSeparatorColor(separatorColor); @@ -122,8 +122,8 @@ public class ChangeType { } @Nullable - private static RangeHighlighter addLine(ChangeHighlighterHolder markup, int line, TextDiffType type, SeparatorPlacement placement) { - RangeHighlighter highlighter = markup.addLineHighlighter(line, LAYER, type); + private RangeHighlighter addLine(ChangeHighlighterHolder markup, int line, TextDiffType type, SeparatorPlacement placement) { + RangeHighlighter highlighter = markup.addLineHighlighter(line, LAYER, type, myApplied); if (highlighter == null) { return null; } diff --git a/plugins/git4idea/src/git4idea/actions/GitUnstash.java b/plugins/git4idea/src/git4idea/actions/GitUnstash.java index 0715c8b46e45..2eb28c6caf2a 100644 --- a/plugins/git4idea/src/git4idea/actions/GitUnstash.java +++ b/plugins/git4idea/src/git4idea/actions/GitUnstash.java @@ -20,7 +20,6 @@ import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vcs.changes.ChangeListManager; import com.intellij.openapi.vfs.VirtualFile; import git4idea.i18n.GitBundle; -import git4idea.repo.GitRepositoryManager; import git4idea.ui.GitUnstashDialog; import org.jetbrains.annotations.NotNull; @@ -50,6 +49,11 @@ public class GitUnstash extends GitRepositoryAction { final List exceptions) throws VcsException { final ChangeListManager changeListManager = ChangeListManager.getInstance(project); if (changeListManager.isFreezedWithNotification("Can not unstash changes now")) return; - GitUnstashDialog.showUnstashDialog(project, gitRoots, defaultRoot, affectedRoots); + GitUnstashDialog.showUnstashDialog(project, gitRoots, defaultRoot); + } + + @Override + protected boolean executeFinalTasksSynchronously() { + return false; } } diff --git a/plugins/git4idea/src/git4idea/commands/GitHandlerUtil.java b/plugins/git4idea/src/git4idea/commands/GitHandlerUtil.java index 05b8246dd7ab..03cfab25bc84 100644 --- a/plugins/git4idea/src/git4idea/commands/GitHandlerUtil.java +++ b/plugins/git4idea/src/git4idea/commands/GitHandlerUtil.java @@ -372,12 +372,6 @@ public class GitHandlerUtil { } } } - /** - * Error indicators for the line - */ - @NonNls private static final String[] ERROR_INDICATORS = - {"ERROR:", "error", "FATAL:", "fatal", "Cannot apply", "Could not", "Interactive rebase already started", "refusing to pull", - "cannot rebase:"}; /** * Check if the line is an error line @@ -386,7 +380,7 @@ public class GitHandlerUtil { * @return true if the error line */ protected static boolean isErrorLine(String text) { - for (String prefix : ERROR_INDICATORS) { + for (String prefix : GitImpl.ERROR_INDICATORS) { if (text.startsWith(prefix)) { return true; } diff --git a/plugins/git4idea/src/git4idea/commands/GitImpl.java b/plugins/git4idea/src/git4idea/commands/GitImpl.java index 9f9eeae22688..29d6be84a3cb 100644 --- a/plugins/git4idea/src/git4idea/commands/GitImpl.java +++ b/plugins/git4idea/src/git4idea/commands/GitImpl.java @@ -339,14 +339,14 @@ public class GitImpl implements Git { } } - private GitCommandResult run(@NotNull GitLineHandler handler) { + private static GitCommandResult run(@NotNull GitLineHandler handler) { return run(handler, false); } /** * Runs the given {@link GitLineHandler} in the current thread and returns the {@link GitCommandResult}. */ - private GitCommandResult run(@NotNull GitLineHandler handler, boolean remote) { + private static GitCommandResult run(@NotNull GitLineHandler handler, boolean remote) { handler.setNoSSH(!remote); final List errorOutput = new ArrayList(); @@ -387,7 +387,7 @@ public class GitImpl implements Git { /** * Check if the line looks line an error message */ - private boolean isError(String text) { + private static boolean isError(String text) { for (String indicator : ERROR_INDICATORS) { if (text.startsWith(indicator.toLowerCase())) { return true; @@ -397,8 +397,9 @@ public class GitImpl implements Git { } // could be upper-cased, so should check case-insensitively - private final String[] ERROR_INDICATORS = { - "error", "fatal", "Cannot apply", "Could not", "Interactive rebase already started", "refusing to pull", "cannot rebase:", "conflict" + public static final String[] ERROR_INDICATORS = { + "error", "fatal", "Cannot apply", "Could not", "Interactive rebase already started", "refusing to pull", "cannot rebase:", "conflict", + "unable" }; } diff --git a/plugins/git4idea/src/git4idea/push/GitPusher.java b/plugins/git4idea/src/git4idea/push/GitPusher.java index ebb558aec8fe..b150324b3218 100644 --- a/plugins/git4idea/src/git4idea/push/GitPusher.java +++ b/plugins/git4idea/src/git4idea/push/GitPusher.java @@ -15,6 +15,7 @@ */ package git4idea.push; +import com.intellij.notification.Notification; import com.intellij.notification.NotificationType; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.diagnostic.Logger; @@ -45,6 +46,7 @@ import git4idea.repo.GitRepository; import git4idea.repo.GitRepositoryManager; import git4idea.settings.GitPushSettings; import git4idea.update.GitUpdateProcess; +import git4idea.update.GitUpdateResult; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -546,12 +548,31 @@ public final class GitPusher { private boolean update(@NotNull Collection rootsToUpdate, @NotNull UpdateMethod updateMethod) { GitUpdateProcess.UpdateMethod um = updateMethod == UpdateMethod.MERGE ? GitUpdateProcess.UpdateMethod.MERGE : GitUpdateProcess.UpdateMethod.REBASE; - boolean updateResult = new GitUpdateProcess(myProject, myProgressIndicator, new HashSet(rootsToUpdate), + GitUpdateResult updateResult = new GitUpdateProcess(myProject, myProgressIndicator, new HashSet(rootsToUpdate), UpdatedFiles.create()).update(um); for (GitRepository repository : rootsToUpdate) { repository.getRoot().refresh(true, true); } - return updateResult; + if (updateResult == GitUpdateResult.SUCCESS) { + return true; + } + else if (updateResult == GitUpdateResult.SUCCESS_WITH_RESOLVED_CONFLICTS || updateResult == GitUpdateResult.INCOMPLETE) { + String title = "Push cancelled"; + String description; + if (updateResult == GitUpdateResult.INCOMPLETE) { + description = "Push has been cancelled, because not all conflicts were resolved during update.
" + + "Resolve the conflicts and invoke push again."; + } + else { + description = "Push has been cancelled, because there were conflicts during update.
" + + "Check that conflicts were resolved correctly, and invoke push again."; + } + new Notification(GitVcs.MINOR_NOTIFICATION.getDisplayId(), title, description, NotificationType.WARNING).notify(myProject); + return false; + } + else { + return false; + } } } diff --git a/plugins/git4idea/src/git4idea/stash/GitStashChangesSaver.java b/plugins/git4idea/src/git4idea/stash/GitStashChangesSaver.java index 48bb90ea6839..8a5286351c3d 100644 --- a/plugins/git4idea/src/git4idea/stash/GitStashChangesSaver.java +++ b/plugins/git4idea/src/git4idea/stash/GitStashChangesSaver.java @@ -99,7 +99,7 @@ public class GitStashChangesSaver extends GitChangesSaver { @Override protected void showSavedChanges() { - GitUnstashDialog.showUnstashDialog(myProject, new ArrayList(myStashedRoots), myStashedRoots.iterator().next(), new HashSet()); + GitUnstashDialog.showUnstashDialog(myProject, new ArrayList(myStashedRoots), myStashedRoots.iterator().next()); } @Override @@ -216,8 +216,8 @@ public class GitStashChangesSaver extends GitChangesSaver { if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { if (event.getDescription().equals("saver")) { // we don't use #showSavedChanges to specify unmerged root first - GitUnstashDialog.showUnstashDialog(myProject, new ArrayList(myStashedRoots), myStashedRoots.iterator().next(), - new HashSet()); + GitUnstashDialog.showUnstashDialog(myProject, new ArrayList(myStashedRoots), myStashedRoots.iterator().next() + ); } else if (event.getDescription().equals("resolve")) { mergeNoProceed(); } diff --git a/plugins/git4idea/src/git4idea/ui/GitUnstashDialog.java b/plugins/git4idea/src/git4idea/ui/GitUnstashDialog.java index bf3d7793306b..df7051f224de 100644 --- a/plugins/git4idea/src/git4idea/ui/GitUnstashDialog.java +++ b/plugins/git4idea/src/git4idea/ui/GitUnstashDialog.java @@ -390,26 +390,10 @@ public class GitUnstashDialog extends DialogWrapper { return myStashList; } - /** - * Show unstash dialog and process its result - * - * @param project the context project - * @param gitRoots the git roots - * @param defaultRoot the default git root - * @param affectedRoots the affected roots - */ - public static void showUnstashDialog(Project project, - List gitRoots, - VirtualFile defaultRoot, - Set affectedRoots) { - GitUnstashDialog d = new GitUnstashDialog(project, gitRoots, defaultRoot); - d.show(); - if (!d.isOK()) { - return; - } - VirtualFile root = d.getGitRoot(); - affectedRoots.add(root); - GitLineHandler h = d.handler(); + @Override + protected void doOKAction() { + VirtualFile root = getGitRoot(); + GitLineHandler h = handler(); final AtomicBoolean conflict = new AtomicBoolean(); h.addLineListener(new GitLineHandlerAdapter() { @@ -423,11 +407,17 @@ public class GitUnstashDialog extends DialogWrapper { root.refresh(true, true); if (conflict.get()) { - boolean conflictsResolved = new UnstashConflictResolver(project, root, d.getSelectedStash()).merge(); + boolean conflictsResolved = new UnstashConflictResolver(myProject, root, getSelectedStash()).merge(); LOG.info("loadRoot " + root + ", conflictsResolved: " + conflictsResolved); } else if (rc != 0) { - GitUIUtil.showOperationErrors(project, h.errors(), h.printableCommandLine()); + GitUIUtil.showOperationErrors(myProject, h.errors(), h.printableCommandLine()); } + super.doOKAction(); + } + + public static void showUnstashDialog(Project project, List gitRoots, VirtualFile defaultRoot) { + new GitUnstashDialog(project, gitRoots, defaultRoot).show(); + // d is not modal=> everything else in doOKAction. } private static class UnstashConflictResolver extends GitConflictResolver { diff --git a/plugins/git4idea/src/git4idea/update/GitMergeUpdater.java b/plugins/git4idea/src/git4idea/update/GitMergeUpdater.java index 1360c937e990..6d4c72597fac 100644 --- a/plugins/git4idea/src/git4idea/update/GitMergeUpdater.java +++ b/plugins/git4idea/src/git4idea/update/GitMergeUpdater.java @@ -113,7 +113,7 @@ public class GitMergeUpdater extends GitUpdater { LOG.info("Conflict detected"); final boolean allMerged = new MyConflictResolver(myProject, myGit, merger, myRoot).merge(); - return allMerged ? GitUpdateResult.SUCCESS : GitUpdateResult.INCOMPLETE; + return allMerged ? GitUpdateResult.SUCCESS_WITH_RESOLVED_CONFLICTS : GitUpdateResult.INCOMPLETE; } else if (error == MergeError.LOCAL_CHANGES) { LOG.info("Local changes would be overwritten by merge"); diff --git a/plugins/git4idea/src/git4idea/update/GitRebaseUpdater.java b/plugins/git4idea/src/git4idea/update/GitRebaseUpdater.java index 74b7df43e02b..be59067a6cfb 100644 --- a/plugins/git4idea/src/git4idea/update/GitRebaseUpdater.java +++ b/plugins/git4idea/src/git4idea/update/GitRebaseUpdater.java @@ -105,7 +105,7 @@ public class GitRebaseUpdater extends GitUpdater { if (rebaseConflictDetector.isMergeConflict()) { LOG.info("handleRebaseFailure merge conflict"); final boolean allMerged = new MyConflictResolver(myProject, myGit, myRoot, myRebaser).merge(); - return allMerged ? GitUpdateResult.SUCCESS : GitUpdateResult.INCOMPLETE; + return allMerged ? GitUpdateResult.SUCCESS_WITH_RESOLVED_CONFLICTS : GitUpdateResult.INCOMPLETE; } else if (untrackedWouldBeOverwrittenDetector.wasMessageDetected()) { LOG.info("handleRebaseFailure: untracked files would be overwritten by checkout"); UntrackedFilesNotifier.notifyUntrackedFilesOverwrittenBy(myProject, ServiceManager.getService(myProject, PlatformFacade.class), diff --git a/plugins/git4idea/src/git4idea/update/GitUpdateEnvironment.java b/plugins/git4idea/src/git4idea/update/GitUpdateEnvironment.java index 1ef496047022..0fa3515fdf7c 100644 --- a/plugins/git4idea/src/git4idea/update/GitUpdateEnvironment.java +++ b/plugins/git4idea/src/git4idea/update/GitUpdateEnvironment.java @@ -66,7 +66,7 @@ public class GitUpdateEnvironment implements UpdateEnvironment { GitRepositoryManager repositoryManager = getRepositoryManager(myProject); final GitUpdateProcess gitUpdateProcess = new GitUpdateProcess(myProject, progressIndicator, getRepositoriesFromRoots(repositoryManager, roots), updatedFiles); - boolean result = gitUpdateProcess.update(GitUpdateProcess.UpdateMethod.READ_FROM_SETTINGS); + boolean result = gitUpdateProcess.update(GitUpdateProcess.UpdateMethod.READ_FROM_SETTINGS).isSuccess(); return new GitUpdateSession(result); } diff --git a/plugins/git4idea/src/git4idea/update/GitUpdateProcess.java b/plugins/git4idea/src/git4idea/update/GitUpdateProcess.java index 4a7ac4604fbd..0602ce75c7cd 100644 --- a/plugins/git4idea/src/git4idea/update/GitUpdateProcess.java +++ b/plugins/git4idea/src/git4idea/update/GitUpdateProcess.java @@ -42,6 +42,7 @@ import git4idea.repo.GitBranchTrackInfo; import git4idea.repo.GitRepository; import git4idea.stash.GitChangesSaver; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Collection; import java.util.HashMap; @@ -67,7 +68,7 @@ public class GitUpdateProcess { private final GitChangesSaver mySaver; private final Map myTrackedBranches = new HashMap(); - private boolean myResult; + private GitUpdateResult myResult; private final Map myUpdaters; private final Collection myRootsToSave; @@ -94,12 +95,7 @@ public class GitUpdateProcess { /** * Checks if update is possible, saves local changes and updates all roots. * In case of error shows notification and returns false. If update completes without errors, returns true. - */ - public boolean update() { - return update(UpdateMethod.READ_FROM_SETTINGS); - } - - /** + * * Perform update on all roots. * 0. Blocks reloading project on external change, saving/syncing on frame deactivation. * 1. Checks if update is possible (rebase/merge in progress, no tracked branches...) and provides merge dialog to solve problems. @@ -110,18 +106,19 @@ public class GitUpdateProcess { * local changes are not restored. * */ - public boolean update(final UpdateMethod updateMethod) { + @NotNull + public GitUpdateResult update(final UpdateMethod updateMethod) { LOG.info("update started|" + updateMethod); String oldText = myProgressIndicator.getText(); myProgressIndicator.setText("Updating..."); // check if update is possible if (checkRebaseInProgress() || isMergeInProgress() || areUnmergedFiles() || !checkTrackedBranchesConfigured()) { - return false; + return GitUpdateResult.NOT_READY; } if (!fetchAndNotify()) { - return false; + return GitUpdateResult.NOT_READY; } GitComplexProcess.Operation updateOperation = new GitComplexProcess.Operation() { @@ -135,7 +132,8 @@ public class GitUpdateProcess { return myResult; } - private boolean updateImpl(UpdateMethod updateMethod, ContinuationContext context) { + @NotNull + private GitUpdateResult updateImpl(UpdateMethod updateMethod, ContinuationContext context) { // define updaters for roots LOG.info("updateImpl: defining updaters..."); try { @@ -158,10 +156,10 @@ public class GitUpdateProcess { } catch (VcsException e) { LOG.info(e); notifyError(myProject, "Git update failed", e.getMessage(), true, e); - return false; + return GitUpdateResult.ERROR; } - if (myUpdaters.isEmpty()) return true; + if (myUpdaters.isEmpty()) return GitUpdateResult.NOTHING_TO_UPDATE; // save local changes if needed (update via merge may perform without saving). LOG.info("updateImpl: identifying if save is needed..."); @@ -182,13 +180,13 @@ public class GitUpdateProcess { notifyError(myProject, "Git update failed", "Tried to save uncommitted changes in " + mySaver.getSaverName() + " before update, but failed with an error.
" + "Update was cancelled.", true, e); - return false; + return GitUpdateResult.ERROR; } // update each root LOG.info("updateImpl: updating..."); boolean incomplete = false; - boolean success = true; + GitUpdateResult compoundResult = null; VirtualFile currentlyUpdatedRoot = null; try { for (Map.Entry entry : myUpdaters.entrySet()) { @@ -199,7 +197,7 @@ public class GitUpdateProcess { if (res == GitUpdateResult.INCOMPLETE) { incomplete = true; } - success &= res.isSuccess(); + compoundResult = joinResults(compoundResult, res); } } catch (VcsException e) { String rootName = (currentlyUpdatedRoot == null) ? "" : currentlyUpdatedRoot.getName(); @@ -207,7 +205,7 @@ public class GitUpdateProcess { notifyImportantError(myProject, "Error updating " + rootName, "Updating " + rootName + " failed with an error: " + e.getLocalizedMessage()); } finally { - if (incomplete || !success) { + if (incomplete || !!compoundResult.isSuccess()) { mySaver.notifyLocalChangesAreNotRestored(); } else { @@ -215,7 +213,15 @@ public class GitUpdateProcess { restoreLocalChanges(context); } } - return success; + return compoundResult; + } + + @NotNull + private static GitUpdateResult joinResults(@Nullable GitUpdateResult compoundResult, GitUpdateResult result) { + if (compoundResult == null) { + return result; + } + return compoundResult.join(result); } private void restoreLocalChanges(ContinuationContext context) { diff --git a/plugins/git4idea/src/git4idea/update/GitUpdateResult.java b/plugins/git4idea/src/git4idea/update/GitUpdateResult.java index 323060120313..215cbb688224 100644 --- a/plugins/git4idea/src/git4idea/update/GitUpdateResult.java +++ b/plugins/git4idea/src/git4idea/update/GitUpdateResult.java @@ -15,19 +15,43 @@ */ package git4idea.update; +import org.jetbrains.annotations.NotNull; + /** * @author Kirill Likhodedov */ public enum GitUpdateResult { - SUCCESS, - /** User cancelled update, everything that has changed was rolled back (git rebase/merge --abort) */ - CANCEL, - /** exception happened during update */ - ERROR, + /** Nothing to update. */ + NOTHING_TO_UPDATE(1), + /** Successful update, without merge conflict resolution during update. */ + SUCCESS(2), + /** Update introduced a merge conflict, that was immediately resolved by user. */ + SUCCESS_WITH_RESOLVED_CONFLICTS(3), /** Update introduced a merge conflict that wasn't immediately resolved. */ - INCOMPLETE; + INCOMPLETE(4), + /** User cancelled update, everything that has changed was rolled back (git rebase/merge --abort) */ + CANCEL(5), + /** An error happened during update */ + ERROR(6), + /** Update is not possible due to a configuration error or because of a failed fetch. */ + NOT_READY(7); + + private final int myPriority; + + GitUpdateResult(int priority) { + myPriority = priority; + } public boolean isSuccess() { - return this == SUCCESS || this == INCOMPLETE; + return this == SUCCESS || this == SUCCESS_WITH_RESOLVED_CONFLICTS || this == INCOMPLETE || this == NOTHING_TO_UPDATE; } + + @NotNull + public GitUpdateResult join(@NotNull GitUpdateResult next) { + if (myPriority >= next.myPriority) { + return this; + } + return next; + } + }