Search in sources :

Example 1 with IExecutionResult

use of com.virtuslab.gitmachete.backend.api.hooks.IExecutionResult in project git-machete-intellij-plugin by VirtusLab.

the class BaseRebaseBranchOntoParentAction method doRebase.

private void doRebase(Project project, GitRepository gitRepository, IGitMacheteRepositorySnapshot gitMacheteRepositorySnapshot, INonRootManagedBranchSnapshot branchToRebase, boolean shouldExplicitlyCheckout) {
    LOG.debug(() -> "Entering: project = ${project}, gitRepository = ${gitRepository}, branchToRebase = ${branchToRebase}");
    val tryGitRebaseParameters = Try.of(() -> branchToRebase.getParametersForRebaseOntoParent());
    if (tryGitRebaseParameters.isFailure()) {
        val e = tryGitRebaseParameters.getCause();
        // TODO (#172): redirect the user to the manual fork-point
        val message = e.getMessage() == null ? "Unable to get rebase parameters." : e.getMessage();
        LOG.error(message);
        IntelliJNotificationCompat.notifyError(project, getString("action.GitMachete.BaseRebaseBranchOntoParentAction.notification.title.rebase-fail"), message);
        return;
    }
    val gitRebaseParameters = tryGitRebaseParameters.get();
    LOG.debug(() -> "Queuing machete-pre-rebase hooks background task for '${branchToRebase.getName()}' branch");
    new Task.Backgroundable(project, getString("action.GitMachete.BaseRebaseBranchOntoParentAction.hook.task-title")) {

        @Override
        @UIThreadUnsafe
        public void run(ProgressIndicator indicator) {
            AtomicReference<Try<Option<IExecutionResult>>> wrapper = new AtomicReference<>(Try.success(Option.none()));
            new GitFreezingProcess(project, myTitle, () -> {
                LOG.info("Executing machete-pre-rebase hooks");
                val hookResult = Try.of(() -> gitMacheteRepositorySnapshot.executeMachetePreRebaseHookIfPresent(gitRebaseParameters));
                wrapper.set(hookResult);
            }).execute();
            Try<Option<IExecutionResult>> hookResult = wrapper.get();
            if (hookResult == null) {
                // Not really possible, it's here just to calm down Checker Framework.
                return;
            }
            if (hookResult.isFailure()) {
                val message = "machete-pre-rebase hooks refused to rebase ${NL}error: ${hookResult.getCause().getMessage()}";
                LOG.error(message);
                IntelliJNotificationCompat.notifyError(project, getString("action.GitMachete.BaseRebaseBranchOntoParentAction.notification.title.rebase-abort"), message);
                return;
            }
            val maybeExecutionResult = hookResult.get();
            if (maybeExecutionResult.isDefined() && maybeExecutionResult.get().getExitCode() != 0) {
                val message = "machete-pre-rebase hooks refused to rebase (exit code ${maybeExecutionResult.get().getExitCode()})";
                LOG.error(message);
                val executionResult = maybeExecutionResult.get();
                val stdoutOption = executionResult.getStdout();
                val stderrOption = executionResult.getStderr();
                IntelliJNotificationCompat.notifyError(project, getString("action.GitMachete.BaseRebaseBranchOntoParentAction.notification.title.rebase-abort"), message + (!stdoutOption.trim().isEmpty() ? NL + "stdout:" + NL + stdoutOption : "") + (!stderrOption.trim().isEmpty() ? NL + "stderr:" + NL + stderrOption : ""));
                return;
            }
            LOG.debug(() -> "Queuing rebase background task for '${branchToRebase.getName()}' branch");
            new Task.Backgroundable(project, getString("action.GitMachete.BaseRebaseBranchOntoParentAction.task-title")) {

                @Override
                @UIThreadUnsafe
                public void run(ProgressIndicator indicator) {
                    GitRebaseParams params = getIdeaRebaseParamsOf(gitRepository, gitRebaseParameters);
                    LOG.info("Rebasing '${gitRebaseParameters.getCurrentBranch().getName()}' branch " + "until ${gitRebaseParameters.getForkPointCommit().getHash()} commit " + "onto ${gitRebaseParameters.getNewBaseBranch().getName()}");
                    /*
             * Git4Idea ({@link git4idea.rebase.GitRebaseUtils#rebase}) does not allow to rebase in detached head state.
             * However, it is possible with Git (performing checkout implicitly) and should be allowed in the case of
             * "Checkout and Rebase Onto Parent" Action. To pass the git4idea check in such a case we checkout the branch
             * explicitly and then perform the actual rebase.
             */
                    if (shouldExplicitlyCheckout) {
                        CheckoutSelectedBranchAction.doCheckout(project, indicator, gitRebaseParameters.getCurrentBranch().getName(), gitRepository);
                    }
                    GitRebaseUtils.rebase(project, Collections.singletonList(gitRepository), params, indicator);
                }
            }.queue();
        }
    }.queue();
}
Also used : lombok.val(lombok.val) GitFreezingProcess(git4idea.util.GitFreezingProcess) Task(com.intellij.openapi.progress.Task) AtomicReference(java.util.concurrent.atomic.AtomicReference) IExecutionResult(com.virtuslab.gitmachete.backend.api.hooks.IExecutionResult) ProgressIndicator(com.intellij.openapi.progress.ProgressIndicator) GitRebaseParams(git4idea.branch.GitRebaseParams) Option(io.vavr.control.Option) Try(io.vavr.control.Try) UIThreadUnsafe(com.virtuslab.qual.guieffect.UIThreadUnsafe)

Aggregations

ProgressIndicator (com.intellij.openapi.progress.ProgressIndicator)1 Task (com.intellij.openapi.progress.Task)1 IExecutionResult (com.virtuslab.gitmachete.backend.api.hooks.IExecutionResult)1 UIThreadUnsafe (com.virtuslab.qual.guieffect.UIThreadUnsafe)1 GitRebaseParams (git4idea.branch.GitRebaseParams)1 GitFreezingProcess (git4idea.util.GitFreezingProcess)1 Option (io.vavr.control.Option)1 Try (io.vavr.control.Try)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1 lombok.val (lombok.val)1