org.eclipse.egit.gitflow.ui.internal.actions.FeatureCheckoutHandler.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.egit.gitflow.ui.internal.actions.FeatureCheckoutHandler.java

Source

/*******************************************************************************
 * Copyright (C) 2015, Max Hohenegger <eclipse@hohenegger.eu>
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *******************************************************************************/
package org.eclipse.egit.gitflow.ui.internal.actions;

import static org.eclipse.egit.gitflow.ui.Activator.error;
import static org.eclipse.egit.gitflow.ui.internal.JobFamilies.GITFLOW_FAMILY;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.IJobManager;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.egit.core.internal.job.JobUtil;
import org.eclipse.egit.gitflow.GitFlowRepository;
import org.eclipse.egit.gitflow.op.FeatureCheckoutOperation;
import org.eclipse.egit.gitflow.ui.internal.JobFamilies;
import org.eclipse.egit.gitflow.ui.internal.UIText;
import org.eclipse.egit.gitflow.ui.internal.dialogs.FeatureBranchSelectionDialog;
import org.eclipse.egit.ui.internal.branch.CleanupUncomittedChangesDialog;
import org.eclipse.jface.window.Window;
import org.eclipse.jgit.api.CheckoutResult;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.handlers.HandlerUtil;

/**
 * git flow feature checkout
 */
public class FeatureCheckoutHandler extends AbstractHandler {
    @Override
    public Object execute(ExecutionEvent event) throws ExecutionException {
        final GitFlowRepository gfRepo = GitFlowHandlerUtil.getRepository(event);
        if (gfRepo == null) {
            return error(UIText.Handlers_noGitflowRepositoryFound);
        }

        Repository repository = gfRepo.getRepository();

        final List<Ref> refs = gfRepo.getFeatureBranches();

        FeatureBranchSelectionDialog dialog = new FeatureBranchSelectionDialog(HandlerUtil.getActiveShell(event),
                refs, UIText.FeatureCheckoutHandler_selectFeature, UIText.FeatureCheckoutHandler_localFeatures,
                Constants.R_HEADS + gfRepo.getConfig().getFeaturePrefix(), gfRepo);

        if (dialog.open() != Window.OK) {
            return null;
        }
        final Ref ref = dialog.getSelectedNode();

        try {
            String featureName = gfRepo.getFeatureBranchName(ref);
            // TODO: consider using BranchOperationUI because checkout can take
            // a long time on large repositories
            FeatureCheckoutOperation checkoutOperation = new FeatureCheckoutOperation(gfRepo, featureName);
            JobUtil.scheduleUserWorkspaceJob(checkoutOperation, UIText.FeatureCheckoutHandler_checkingOutFeature,
                    JobFamilies.GITFLOW_FAMILY);
            IJobManager jobMan = Job.getJobManager();
            try {
                jobMan.join(GITFLOW_FAMILY, null);
            } catch (OperationCanceledException | InterruptedException e) {
                return error(e.getMessage(), e);
            }

            CheckoutResult result = checkoutOperation.getResult();
            if (!CheckoutResult.Status.OK.equals(result.getStatus())) {
                Shell shell = HandlerUtil.getActiveShell(event);
                if (!handleUncommittedFiles(gfRepo.getRepository(), shell, repository.getWorkTree().getName())) {
                    return Status.CANCEL_STATUS;
                } else {
                    JobUtil.scheduleUserWorkspaceJob(checkoutOperation,
                            UIText.FeatureCheckoutHandler_checkingOutFeature, JobFamilies.GITFLOW_FAMILY);
                }
            }
        } catch (GitAPIException e) {
            throw new RuntimeException(e);
        }

        return null;
    }

    private boolean handleUncommittedFiles(Repository repo, Shell shell, String repoName) throws GitAPIException {
        try (Git git = new Git(repo)) {
            org.eclipse.jgit.api.Status status = git.status().call();

            if (status.hasUncommittedChanges()) {
                List<String> files = new ArrayList<String>(status.getUncommittedChanges());
                Collections.sort(files);
                CleanupUncomittedChangesDialog cleanupUncomittedChangesDialog = new CleanupUncomittedChangesDialog(
                        shell, MessageFormat.format(UIText.FeatureCheckoutHandler_cleanupDialog_title, repoName),
                        UIText.FeatureCheckoutHandler_cleanupDialog_text, repo, files);
                cleanupUncomittedChangesDialog.open();
                return cleanupUncomittedChangesDialog.shouldContinue();
            } else {
                return true;
            }
        }
    }
}