org.flowerplatform.web.git.operation.CheckoutOperation.java Source code

Java tutorial

Introduction

Here is the source code for org.flowerplatform.web.git.operation.CheckoutOperation.java

Source

/* license-start
 * 
 * Copyright (C) 2008 - 2013 Crispico, <http://www.crispico.com/>.
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation version 3.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details, at <http://www.gnu.org/licenses/>.
 * 
 * Contributors:
 *   Crispico - Initial API and implementation
 *
 * license-end
 */
package org.flowerplatform.web.git.operation;

import java.io.File;
import java.util.List;

import org.eclipse.jgit.api.CheckoutCommand;
import org.eclipse.jgit.api.CheckoutResult;
import org.eclipse.jgit.api.CreateBranchCommand.SetupUpstreamMode;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.transport.RefSpec;
import org.eclipse.jgit.transport.URIish;
import org.flowerplatform.common.CommonPlugin;
import org.flowerplatform.communication.channel.CommunicationChannel;
import org.flowerplatform.communication.command.DisplaySimpleMessageClientCommand;
import org.flowerplatform.communication.progress_monitor.ProgressMonitor;
import org.flowerplatform.web.git.GitPlugin;
import org.flowerplatform.web.git.GitUtils;
import org.flowerplatform.web.git.remote.dto.GitRef;
import org.flowerplatform.web.git.remote.dto.RemoteConfig;

/**
 * @author Cristina Constantinescu
 */
public class CheckoutOperation {

    private Object node;
    private Repository repository;
    private String name;
    private RemoteConfig remote;
    private GitRef upstreamBranch;
    private boolean rebase;
    private CommunicationChannel channel;

    public CheckoutOperation(Object node, Repository repository, String name, RemoteConfig remote,
            GitRef upstreamBranch, boolean rebase, CommunicationChannel channel) {
        this.node = node;
        this.repository = repository;
        this.name = name;
        this.remote = remote;
        this.upstreamBranch = upstreamBranch;
        this.rebase = rebase;
        this.channel = channel;
    }

    public boolean execute() {
        ProgressMonitor monitor = ProgressMonitor
                .create(GitPlugin.getInstance().getMessage("git.checkout.monitor.title"), channel);

        try {
            monitor.beginTask(
                    GitPlugin.getInstance().getMessage("git.checkout.monitor.message", new Object[] { name }), 4);
            monitor.setTaskName("Getting remote branch...");
            Git git = new Git(repository);
            Ref ref;
            if (node instanceof Ref) {
                ref = (Ref) node;
            } else {
                // get remote branch
                String dst = Constants.R_REMOTES + remote.getName();
                String remoteRefName = dst + "/" + upstreamBranch.getShortName();
                ref = repository.getRef(remoteRefName);
                if (ref == null) { // doesn't exist, fetch it
                    RefSpec refSpec = new RefSpec();
                    refSpec = refSpec.setForceUpdate(true);
                    refSpec = refSpec.setSourceDestination(upstreamBranch.getName(), remoteRefName);

                    git.fetch().setRemote(new URIish(remote.getUri()).toPrivateString()).setRefSpecs(refSpec)
                            .call();

                    ref = repository.getRef(remoteRefName);
                }
            }
            monitor.worked(1);
            monitor.setTaskName("Creating local branch...");

            // create local branch
            git.branchCreate().setName(name).setStartPoint(ref.getName())
                    .setUpstreamMode(SetupUpstreamMode.SET_UPSTREAM).call();

            if (!(node instanceof Ref)) {
                // save upstream configuration
                StoredConfig config = repository.getConfig();

                config.setString(ConfigConstants.CONFIG_BRANCH_SECTION, name, ConfigConstants.CONFIG_KEY_MERGE,
                        upstreamBranch.getName());

                config.setString(ConfigConstants.CONFIG_BRANCH_SECTION, name, ConfigConstants.CONFIG_KEY_REMOTE,
                        remote.getName());

                if (rebase) {
                    config.setBoolean(ConfigConstants.CONFIG_BRANCH_SECTION, name,
                            ConfigConstants.CONFIG_KEY_REBASE, true);
                } else {
                    config.unset(ConfigConstants.CONFIG_BRANCH_SECTION, name, ConfigConstants.CONFIG_KEY_REBASE);
                }
                config.save();
            }
            monitor.worked(1);
            monitor.setTaskName("Creating working directory");

            // create working directory for local branch
            File mainRepoFile = repository.getDirectory().getParentFile();
            File wdirFile = new File(mainRepoFile.getParentFile(), GitUtils.WORKING_DIRECTORY_PREFIX + name);
            if (wdirFile.exists()) {
                GitPlugin.getInstance().getUtils().delete(wdirFile);
            }
            GitPlugin.getInstance().getUtils().run_git_workdir_cmd(mainRepoFile.getAbsolutePath(),
                    wdirFile.getAbsolutePath());
            monitor.worked(1);
            monitor.setTaskName("Checkout branch");

            // checkout local branch
            Repository wdirRepo = GitPlugin.getInstance().getUtils().getRepository(wdirFile);
            git = new Git(wdirRepo);

            CheckoutCommand cc = git.checkout().setName(name).setForce(true);
            cc.call();

            // show checkout result
            if (cc.getResult().getStatus() == CheckoutResult.Status.CONFLICTS)
                channel.appendOrSendCommand(new DisplaySimpleMessageClientCommand(
                        GitPlugin.getInstance().getMessage("git.checkout.checkoutConflicts.title"),
                        GitPlugin.getInstance().getMessage("git.checkout.checkoutConflicts.message"),
                        cc.getResult().getConflictList().toString(),
                        DisplaySimpleMessageClientCommand.ICON_INFORMATION));

            else if (cc.getResult().getStatus() == CheckoutResult.Status.NONDELETED) {
                // double-check if the files are still there
                boolean show = false;
                List<String> pathList = cc.getResult().getUndeletedList();
                for (String path1 : pathList) {
                    if (new File(wdirRepo.getWorkTree(), path1).exists()) {
                        show = true;
                        break;
                    }
                }
                if (show) {
                    channel.appendOrSendCommand(new DisplaySimpleMessageClientCommand(
                            GitPlugin.getInstance().getMessage("git.checkout.nonDeletedFiles.title"),
                            GitPlugin.getInstance().getMessage("git.checkout.nonDeletedFiles.message",
                                    Repository.shortenRefName(name)),
                            cc.getResult().getUndeletedList().toString(),
                            DisplaySimpleMessageClientCommand.ICON_ERROR));
                }
            } else if (cc.getResult().getStatus() == CheckoutResult.Status.OK) {
                if (ObjectId.isId(wdirRepo.getFullBranch()))
                    channel.appendOrSendCommand(new DisplaySimpleMessageClientCommand(
                            GitPlugin.getInstance().getMessage("git.checkout.detachedHead.title"),
                            GitPlugin.getInstance().getMessage("git.checkout.detachedHead.message"),
                            DisplaySimpleMessageClientCommand.ICON_ERROR));
            }
            monitor.worked(1);
            return true;
        } catch (Exception e) {
            channel.appendOrSendCommand(
                    new DisplaySimpleMessageClientCommand(CommonPlugin.getInstance().getMessage("error"),
                            e.getMessage(), DisplaySimpleMessageClientCommand.ICON_ERROR));
            return false;
        } finally {
            monitor.done();
        }
    }

}