Newer
Older
KisoJikkenNWP / src / main / java / istlab / KisoJikken / GitManager.java

package istlab.KisoJikken;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Set;

import javax.swing.JOptionPane;

import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.PullCommand;
import org.eclipse.jgit.api.StashCreateCommand;
import org.eclipse.jgit.api.Status;
import org.eclipse.jgit.api.StatusCommand;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.errors.NoWorkTreeException;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;

public class GitManager {

    Git git = null;
    Repository repository;
    ConfigManager configman;

    public GitManager(File root) throws IOException {
        repository = Git.open(new File(root.getParentFile().getAbsolutePath() + File.separator + ".git"))
                .getRepository();
        configman = new ConfigManager(App.userhome);
    }

    /**
     * Gitのリポジトリ状況を確認する
     * 
     * @throws NoWorkTreeException
     * @throws GitAPIException
     */
    public void checkClean(boolean skipByConfig) throws NoWorkTreeException, GitAPIException {

        git = new Git(repository);

        StatusCommand statusCommand = git.status();
        Status status = statusCommand.call();

        if (!status.isClean()) {
            // もし、延期ファイルがあって、延期ファイルの日付よりも今日の日付のほうが早いなら、チェックをスキップする(イコールのときはスキップしない)
            if (configman.readAndCheckDate() && skipByConfig)
                return;

            System.out.println("Gitのローカルリポジトリに変更点があります。");
            Set<String> changedFiles = status.getModified();
            Set<String> untrackedFiles = status.getUntracked();

            System.out.println("変更されたファイル:");
            for (String filePath : changedFiles) {
                System.out.println(filePath);
            }
            System.out.println("まだGit管理下にないファイル:");
            for (String filePath : untrackedFiles) {
                System.out.println(filePath);
            }
            JOptionPane.showMessageDialog(Launcher.theapp, "教員提供のSampleSrcが変更されています。\n\n[OK]を押すと、変更されたファイル\n" + //
                    "( git status の実行結果 ) \n" + //
                    "を別ウィンドウで示します。", "NWPフォルダの状況確認", JOptionPane.WARNING_MESSAGE);

            Launcher.theapp.runCommand("git status -s", App.userhome + App.nwp, 600);
            // Launcher.theapp.runCommand("git diff", App.userhome + App.nwp);

            int res = JOptionPane.showConfirmDialog(Launcher.theapp, "変更内容の詳細をみるには cd ~/NWP ; git diff をしてください。\n\n" + //
                    "これまでの変更内容を消して,初期状態に戻しますか?\n\n" + //
                    "「はい」を押すと,変更内容を消して初期状態に戻します。\n" + //
                    "「いいえ」「取消」を押すと,なにもしません。\n\n" + //
                    "あなたがまだ何も作業しておらず,これから実験を\n" + //
                    "始めるときだけ「はい」を押してください。\n" + //
                    "作業の続きを行うときは「いいえ」を押してください。\n" + //
                    "(「いいえ」で回答すると、3日後まで起動時チェックしません。)",
                    "教員提供のSampleSrcが変更されています",
                    JOptionPane.YES_NO_CANCEL_OPTION);
            if (res == JOptionPane.YES_OPTION) {
                int res2 = JOptionPane.showConfirmDialog(Launcher.theapp, "これまでに編集したファイルが消えます。\n本当に消してよいですか?", "ファイルが消えます",
                        JOptionPane.YES_NO_CANCEL_OPTION);
                if (res2 == JOptionPane.YES_OPTION) {
                    stash();
                    pull();
                    JOptionPane.showMessageDialog(Launcher.theapp, "初期状態に戻しました。\n\n誤って削除してしまった場合は、\n $ cd ~/NWP\nをしたあとで\n" + //
                    " $ git stash list (退避情報の一覧)\n"+ //
                    " $ git stash pop  (直前の退避情報を復活) または\n"+//
                    " $ git stash pop stash@{1} (指定した退避情報を復活)\n"+//
                    "を行ってください。");
                }
            } else {
                if (res == JOptionPane.NO_OPTION)
                    configman.write();
            }
        } else {
            if (!skipByConfig) JOptionPane.showMessageDialog(Launcher.theapp, "変更されたファイルはありませんでした。\n\nNo uncommitted changes in the local repository.");
            System.out.println("No uncommitted changes in the local repository.");
        }
        if (git != null)
            git.close();
        // showNotice();
    }

    public void stash() throws GitAPIException {
        git = new Git(repository);

        StashCreateCommand stashCreateCommand = git.stashCreate();
        stashCreateCommand.setIncludeUntracked(true);

        SimpleDateFormat sdf = new SimpleDateFormat("yy/MM/dd HH:mm:ss");

        stashCreateCommand.setWorkingDirectoryMessage(sdf.format(new Date()) + " に退避した作業");
        RevCommit stashCommit = stashCreateCommand.call();

        if (stashCommit != null) {
            System.out.println("Stash created. Stash commit ID: " + stashCommit.getName());
        } else {
            System.out.println("No local changes to stash.");
        }
    }

    public void pull() throws GitAPIException {
        git = new Git(repository);

        PullCommand pullCommand = git.pull();
        pullCommand.call();
    }

    public void showNotice() {
        JOptionPane.showMessageDialog(Launcher.theapp, "(1) デバイスを認識すると,タイトルバーに COM3 のように表示します。\n" + //
                "      複数みえるときはWindowsのデバイスマネージャ>ポートでM5Stickのポート番号を調べたうえで,\n" + //
                "      このプログラムの Serialメニュー から,書き込み先ポートを選んでください。\n\n" + //
                "(2) デバイスを認識しないときは,このプログラムを再起動してみてください。\n" + //
                "     (Appメニュー>このプログラムを再起動する)\n\n" + //
                "(3) デバイスを返却するときは,FactoryTest を書き込んでおいてください。\n" + //
                "     (Fileメニュー>FactoryTestを書き込む)\n\n" + //
                "    デバイスは充電した状態で返却してください。"//
                , "IoTP実験における大事な注意点です。たくさんありますがしっかり読んでください。", JOptionPane.WARNING_MESSAGE);

    }
}