COMMON: COMMANDBAR: Added git command 27/13327/1
authorkh5325.kim <kh5325.kim@samsung.com>
Tue, 3 Dec 2013 11:31:59 +0000 (20:31 +0900)
committerkh5325.kim <kh5325.kim@samsung.com>
Tue, 3 Dec 2013 12:42:05 +0000 (21:42 +0900)
Supports for the git command using jgit-cli.
It runs the git command for the selected resource.

Change-Id: Ib63b061d234fd2d989d574a5fa08ebfb41671f80
Signed-off-by: kh5325.kim <kh5325.kim@samsung.com>
15 files changed:
org.tizen.common.ui/.classpath
org.tizen.common.ui/META-INF/MANIFEST.MF
org.tizen.common.ui/build.properties
org.tizen.common.ui/lib/jgit-cli.jar [new file with mode: 0644]
org.tizen.common.ui/src/org/tizen/common/ui/commandbar/CommandProvider.java
org.tizen.common.ui/src/org/tizen/common/ui/commandbar/Commands.java
org.tizen.common.ui/src/org/tizen/common/ui/commandbar/OrderCommandCallback.java
org.tizen.common.ui/src/org/tizen/common/ui/commandbar/command/GitCommand.java [new file with mode: 0644]
org.tizen.common.ui/src/org/tizen/common/ui/commandbar/command/git/AddCommand.java [new file with mode: 0644]
org.tizen.common.ui/src/org/tizen/common/ui/commandbar/command/git/Command.java [new file with mode: 0644]
org.tizen.common.ui/src/org/tizen/common/ui/commandbar/command/git/JGitCLI.java [new file with mode: 0644]
org.tizen.common.ui/src/org/tizen/common/ui/commandbar/command/git/ResetCommand.java [new file with mode: 0644]
org.tizen.common.ui/src/org/tizen/common/ui/commandbar/command/git/RmCommand.java [new file with mode: 0644]
org.tizen.common.ui/src/org/tizen/common/ui/commandbar/command/git/StatusCommand.java [new file with mode: 0644]
org.tizen.common.ui/src/org/tizen/common/ui/commandbar/command/launcher/CommandLauncher.java

index 6d4c9e1..b1cbcbb 100644 (file)
@@ -10,5 +10,6 @@
        <classpathentry kind="lib" path="lib/jsoup-1.6.3.jar"/>\r
        <classpathentry kind="lib" path="lib/howdoi.jar"/>\r
        <classpathentry kind="lib" path="lib/commons-math3-3.2.jar"/>\r
+       <classpathentry kind="lib" path="lib/jgit-cli.jar"/>\r
        <classpathentry kind="output" path="bin"/>\r
 </classpath>\r
index df21c8c..adc69d7 100644 (file)
@@ -10,6 +10,7 @@ Require-Bundle: org.eclipse.ui,
  org.tizen.common
 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
 Import-Package: org.eclipse.core.resources,
+ org.eclipse.jdt.core,
  org.eclipse.jface.text,
  org.eclipse.ui.console,
  org.eclipse.ui.dialogs,
@@ -33,4 +34,5 @@ Bundle-ClassPath: lib/commons-cli-1.2.jar,
  lib/httpclient-4.2.5.jar,
  lib/httpcore-4.2.4.jar,
  lib/commons-math3-3.2.jar,
+ lib/jgit-cli.jar,
  .
index 90a420c..e188c18 100644 (file)
@@ -17,4 +17,5 @@ bin.includes = META-INF/,\
                about_files/,\
                schema/,\
                lib/commons-math3-3.2.jar,\
-               resources/
+               resources/,\
+               lib/jgit-cli.jar
diff --git a/org.tizen.common.ui/lib/jgit-cli.jar b/org.tizen.common.ui/lib/jgit-cli.jar
new file mode 100644 (file)
index 0000000..6851b34
Binary files /dev/null and b/org.tizen.common.ui/lib/jgit-cli.jar differ
index 7424597..9d8fa97 100644 (file)
@@ -44,6 +44,7 @@ import org.tizen.common.util.ProjectUtil;
 public class CommandProvider extends TextAssistContentProvider implements OrderProcessor {\r
     Pattern PROJECT_COMMAND_PATTERN = Pattern.compile("(@[\\w]+)(\\s.*)*");\r
     Pattern SDB_COMMAND_PATTERN = Pattern.compile("(" + Commands.SDB_COMMAND + ")(\\s.*)*");\r
+    Pattern GIT_COMMAND_PATTERN = Pattern.compile("(" + Commands.GIT_COMMAND + ")(\\s.*)*");\r
 \r
     private int numberOfMostCommons = 3;\r
     private int numberOfHistory = 5;\r
@@ -58,6 +59,7 @@ public class CommandProvider extends TextAssistContentProvider implements OrderP
         void onProject();\r
         void onProjectCommand(String projectName, String arg);\r
         void onSdbCommand(String sdbCommand, String arg);\r
+        void onGitCommand(String gitCommand, String arg);\r
         void onDefault(String arg);\r
     }\r
 \r
@@ -83,6 +85,14 @@ public class CommandProvider extends TextAssistContentProvider implements OrderP
                 callback.onSdbCommand(sdbCommand, arg);\r
             }\r
         }\r
+        else if (key.startsWith(Commands.GIT_COMMAND)) {\r
+            Matcher m = GIT_COMMAND_PATTERN.matcher(key);\r
+            if (m.find()) {\r
+                String gitCommand = m.group(1);\r
+                String arg = m.group(2);\r
+                callback.onGitCommand(gitCommand, arg);\r
+            }\r
+        }\r
         else {\r
             callback.onDefault(key);\r
         }\r
@@ -128,6 +138,13 @@ public class CommandProvider extends TextAssistContentProvider implements OrderP
             }\r
 \r
             @Override\r
+            public void onGitCommand(String gitCommand, String arg) {\r
+                for (String[] cmds : Commands.GIT_COMMANDS) {\r
+                    returnedList.add(new String[] { gitCommand + " " + cmds[0], cmds[1] });\r
+                }\r
+            }\r
+\r
+            @Override\r
             public void onDefault(String arg) {\r
                 returnedList.addAll(getHelpContent(arg));\r
             }\r
index e6c5768..a1e0006 100644 (file)
@@ -42,6 +42,25 @@ public class Commands {
     public final static String IDENTIFIER_SYSTEM_COMMAND = "#";\r
     public final static String HELP_COMMAND = "help";\r
     public final static String PROJECT_COMMAND = "@";\r
+    public final static String GIT_COMMAND = "git";\r
+        public final static String[][] GIT_COMMANDS = {\r
+            { "add",      "Add file contents to the index" },\r
+            { "branch",   "List, create, or delete branches" },\r
+            { "checkout", "Checkout a branch to the working tree" },\r
+            { "clone",    "Clone a repository into a new directory" },\r
+            { "commit",   "Record changes to the repository" },\r
+            { "diff",     "Show diffs" },\r
+            { "fetch",    "Update remote refs from another repository" },\r
+            { "init",     "Create an empty git repository" },\r
+            { "log",      "View commit history" },\r
+            { "merge",    "Merges two development histories" },\r
+            { "push",     "Update remote repository from local refs" },\r
+            { "reset",    "Reset current HEAD to the specified state" },\r
+            { "rm",       "Remove files from the working tree and from the index" },\r
+            { "show",     "Display one commit" },\r
+            { "status",   "Show the working tree status" },\r
+            { "tag",      "Create a tag" }\r
+        };\r
     public final static String QUERY_COMMAND = "query";\r
     public final static String SDB_COMMAND = "sdb";\r
         public final static String[] SDB_COMMANDS = {\r
index 0337285..5009da3 100644 (file)
@@ -131,6 +131,10 @@ public class OrderCommandCallback implements CommandCallback {
     }\r
 \r
     @Override\r
+    public void onGitCommand(String gitCommand, String arg) {\r
+    }\r
+\r
+    @Override\r
     public void onDefault(String arg) {\r
     }\r
 \r
diff --git a/org.tizen.common.ui/src/org/tizen/common/ui/commandbar/command/GitCommand.java b/org.tizen.common.ui/src/org/tizen/common/ui/commandbar/command/GitCommand.java
new file mode 100644 (file)
index 0000000..7ab56c7
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * Common
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Changhyun Lee <changhyun1.lee@samsung.com>
+ * Hyeongseok Heo <hyeongseok.heo@samsung.com>
+ * BonYong Lee <bonyong.lee@samsung.com>
+ * Kangho Kim <kh5325.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+package org.tizen.common.ui.commandbar.command;
+
+import static org.tizen.common.ui.commandbar.command.git.Command.CONTEXT_CONSOLE;
+import static org.tizen.common.ui.commandbar.command.git.Command.CONTEXT_RESOURCE_PATH;
+
+import java.io.PrintStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.tizen.common.core.command.Command;
+import org.tizen.common.core.command.ExecutionContext;
+import org.tizen.common.core.command.Executor;
+import org.tizen.common.ui.commandbar.command.git.*;
+import org.tizen.common.ui.commandbar.command.launcher.CommandLauncher;
+import org.tizen.common.ui.view.console.ConsoleManager;
+import org.tizen.common.util.ArrayUtil;
+import org.tizen.common.util.CollectionUtil;
+import org.tizen.common.util.ViewUtil;
+
+public class GitCommand extends ConsoleCommand {
+    public void run(final Executor executor, final ExecutionContext context) throws Exception {
+        ConsoleManager console = new ConsoleManager(CONSOLE_NAME, true);
+        context.setValue(CONTEXT_CONSOLE, console);
+        IStructuredSelection selection = (IStructuredSelection) ViewUtil.getWorkbenchWindow().getSelectionService().getSelection("org.eclipse.ui.navigator.ProjectExplorer");
+        Object firstElement = selection.getFirstElement();
+        String resource = null;
+        if (firstElement instanceof IResource) {
+            resource = ((IResource) firstElement).getLocation().toPortableString();
+        }
+        else if (firstElement instanceof IPackageFragmentRoot) {
+            resource = ((IPackageFragmentRoot) firstElement).getJavaProject().getProject().getLocation().toPortableString();
+        }
+        context.setValue(CONTEXT_RESOURCE_PATH, resource);
+
+        final String[] opts = (String[]) context.getValue(CommandLauncher.CONTEXT_ARGS);
+        if (ArrayUtil.isEmpty(opts))
+            return;
+
+        runJGitCLI(executor, context, opts);
+    }
+
+    private void runJGitCLI(final Executor executor, final ExecutionContext context, String[] opts) throws Exception {
+        ConsoleManager console = (ConsoleManager) context.getValue(CONTEXT_CONSOLE);
+
+        final PrintStream oldOut = System.out;
+        final PrintStream oldErr = System.err;
+        try {
+            PrintStream out = new PrintStream(console.getMessageConsoleStream());
+            //System.setErr(out);
+            //System.setOut(out);
+
+            JGitCLI cli = new JGitCLI();
+            String resource = (String) context.getValue(CONTEXT_RESOURCE_PATH);
+            cli.setDirectory(resource);
+            cli.setCommand(CollectionUtil.concatenate(opts, " "));
+            cli.run(out);
+        } finally {
+            //System.setErr(oldErr);
+            //System.setOut(oldOut);
+        }
+    }
+
+    /**
+     * Runs custom implementation. It's not currently used because Command Bar uses jgit-cli now.
+     *
+     * <ul>
+     *   <li>git add: {@link org.tizen.common.ui.commandbar.command.git.AddCommand}
+     *   <li>git reset: {@link org.tizen.common.ui.commandbar.command.git.ResetCommand}
+     *   <li>git rm: {@link org.tizen.common.ui.commandbar.command.git.RmCommand}
+     *   <li>git status: {@link org.tizen.common.ui.commandbar.command.git.StatusCommand}
+     * </ul>
+     *
+     * @param executor
+     * @param context
+     * @throws Exception
+     */
+    private void runCustomImpl(final Executor executor, final ExecutionContext context, String[] opts) throws Exception {
+        Map<String, Command> cmds = new HashMap<String, Command>();
+        cmds.put("add", new AddCommand());
+        cmds.put("reset", new ResetCommand());
+        cmds.put("rm", new RmCommand());
+        cmds.put("status", new StatusCommand());
+
+        Command cmd = cmds.get(opts[0]);
+        if (cmd != null)
+            cmd.run(executor, context);
+    }
+}
diff --git a/org.tizen.common.ui/src/org/tizen/common/ui/commandbar/command/git/AddCommand.java b/org.tizen.common.ui/src/org/tizen/common/ui/commandbar/command/git/AddCommand.java
new file mode 100644 (file)
index 0000000..914ec87
--- /dev/null
@@ -0,0 +1,52 @@
+/*\r
+ * Common\r
+ *\r
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
+ *\r
+ * Contact:\r
+ * Changhyun Lee <changhyun1.lee@samsung.com>\r
+ * Hyeongseok Heo <hyeongseok.heo@samsung.com>\r
+ * BonYong Lee <bonyong.lee@samsung.com>\r
+ * Kangho Kim <kh5325.kim@samsung.com>\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ * Contributors:\r
+ * - S-Core Co., Ltd\r
+ *\r
+ */\r
+\r
+package org.tizen.common.ui.commandbar.command.git;\r
+\r
+import org.eclipse.jgit.api.Git;\r
+import org.eclipse.jgit.dircache.DirCache;\r
+import org.eclipse.jgit.lib.Repository;\r
+import org.tizen.common.ui.commandbar.command.launcher.CommandLauncher;\r
+\r
+public class AddCommand extends Command {\r
+    protected void run(Repository repository) throws Exception {\r
+        if (repository != null) {\r
+            Git git = new Git(repository);\r
+\r
+            String[] args = (String[]) getContextValue(CommandLauncher.CONTEXT_ARGS);\r
+            if (args.length == 1) {\r
+                print("Nothing specified, nothing added.\n");\r
+                print("Maybe you wanted to say 'git add .'?\n");\r
+                return;\r
+            }\r
+\r
+            String paths = args[1];\r
+            DirCache dirCache = git.add().addFilepattern(paths).call();\r
+        }\r
+    }\r
+}\r
diff --git a/org.tizen.common.ui/src/org/tizen/common/ui/commandbar/command/git/Command.java b/org.tizen.common.ui/src/org/tizen/common/ui/commandbar/command/git/Command.java
new file mode 100644 (file)
index 0000000..bd0407c
--- /dev/null
@@ -0,0 +1,91 @@
+/*\r
+ * Common\r
+ *\r
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
+ *\r
+ * Contact:\r
+ * Changhyun Lee <changhyun1.lee@samsung.com>\r
+ * Hyeongseok Heo <hyeongseok.heo@samsung.com>\r
+ * BonYong Lee <bonyong.lee@samsung.com>\r
+ * Kangho Kim <kh5325.kim@samsung.com>\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ * Contributors:\r
+ * - S-Core Co., Ltd\r
+ *\r
+ */\r
+\r
+package org.tizen.common.ui.commandbar.command.git;\r
+\r
+import java.io.File;\r
+\r
+import org.eclipse.jgit.lib.Repository;\r
+import org.eclipse.jgit.storage.file.FileRepositoryBuilder;\r
+import org.tizen.common.core.command.ExecutionContext;\r
+import org.tizen.common.core.command.Executor;\r
+import org.tizen.common.ui.view.console.ConsoleManager;\r
+\r
+public abstract class Command implements org.tizen.common.core.command.Command {\r
+    public static final String CONTEXT_CONSOLE = "console";\r
+    public static final String CONTEXT_RESOURCE_PATH = "resource.path";\r
+\r
+    ExecutionContext context;\r
+\r
+    abstract protected void run(Repository repository) throws Exception;\r
+\r
+    protected Object getContextValue(String key) {\r
+        return context.getValue(key);\r
+    }\r
+\r
+    protected ConsoleManager getConsole() {\r
+        return (ConsoleManager) getContextValue(CONTEXT_CONSOLE);\r
+    }\r
+\r
+    protected String getResource() {\r
+        return (String) getContextValue(CONTEXT_RESOURCE_PATH);\r
+    }\r
+\r
+    @Override\r
+    public void run(Executor executor, ExecutionContext context) throws Exception {\r
+        this.context = context;\r
+        ConsoleManager console = (ConsoleManager) context.getValue(CONTEXT_CONSOLE);\r
+\r
+        FileRepositoryBuilder builder = new FileRepositoryBuilder();\r
+        Repository repository = null;\r
+        try {\r
+            repository = builder.findGitDir(new File(getResource())).build();\r
+        } catch (Exception e) {\r
+            getConsole().println("fatal: Not a git repository (or any of the parent directories): .git");\r
+        }\r
+        try {\r
+            run(repository);\r
+        } finally {\r
+            if (repository != null)\r
+                repository.close();\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void undo(Executor executor, ExecutionContext context) throws Exception {\r
+    }\r
+\r
+    @Override\r
+    public Object getResult() {\r
+        return null;\r
+    }\r
+\r
+    protected void print(String line) {\r
+        getConsole().print(line);\r
+    }\r
+}\r
diff --git a/org.tizen.common.ui/src/org/tizen/common/ui/commandbar/command/git/JGitCLI.java b/org.tizen.common.ui/src/org/tizen/common/ui/commandbar/command/git/JGitCLI.java
new file mode 100644 (file)
index 0000000..e099919
--- /dev/null
@@ -0,0 +1,121 @@
+/*\r
+ * Common\r
+ *\r
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
+ *\r
+ * Contact:\r
+ * Changhyun Lee <changhyun1.lee@samsung.com>\r
+ * Hyeongseok Heo <hyeongseok.heo@samsung.com>\r
+ * BonYong Lee <bonyong.lee@samsung.com>\r
+ * Kangho Kim <kh5325.kim@samsung.com>\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ * Contributors:\r
+ * - S-Core Co., Ltd\r
+ *\r
+ */\r
+\r
+package org.tizen.common.ui.commandbar.command.git;\r
+\r
+import java.io.File;\r
+import java.io.PrintStream;\r
+import java.net.URL;\r
+\r
+import org.eclipse.jgit.pgm.Main;\r
+import org.tizen.common.ui.Activator;\r
+import org.tizen.common.util.HostUtil;\r
+import org.tizen.common.util.OSChecker;\r
+import org.tizen.common.util.PluginUtil;\r
+\r
+public class JGitCLI extends Main {\r
+    private String gitdir;\r
+    private String command;\r
+\r
+    protected void run(String[] argv) {\r
+        super.run(argv);\r
+    }\r
+\r
+    public void run(PrintStream out) throws Exception {\r
+        String origDirectory = getDirectory();\r
+        try {\r
+            if (getCommand() == null || getCommand().isEmpty()) {\r
+                // to print "The most commonly used commands are:"\r
+                setDirectory(null);\r
+            }\r
+            /*\r
+            List<String> args = new ArrayList<String>();\r
+            if (getDirectory() != null) {\r
+                args.add("--git-dir");\r
+                args.add(getDirectory() + File.separator + ".git");\r
+            }\r
+            if (getCommand() != null) {\r
+                for (String c : getCommand().split(" "))\r
+                    args.add(c);\r
+            }\r
+            */\r
+\r
+            File gitPath = findGitDir();\r
+            if (gitPath == null) {\r
+                out.println("fatal: Not a git repository (or any of the parent directories): .git");\r
+                return;\r
+            }\r
+            // I'll run jgit-cli by another process:\r
+            //  - To display process OutputStream in ConsoleManager\r
+            //  - To prevent System.exit() codes in org.eclipse.jgit.pgm.Main\r
+            //run(args.toArray(new String[0]));\r
+            URL fileURL = PluginUtil.getFileURLinBundle(Activator.PLUGIN_ID, "lib/jgit-cli.jar");\r
+            String jarPath = fileURL.getPath();\r
+            if (OSChecker.isWindows() && jarPath.startsWith("/")) {\r
+                // /D:/common-eplugin/org.tizen.common.ui/lib/jgit-cli.jar\r
+                jarPath = jarPath.substring(1);\r
+            }\r
+            String command = String.format("java -jar %s --git-dir %s %s", jarPath, gitPath, getCommand());\r
+            String returnExecute = HostUtil.returnExecute(command, null, true);\r
+            out.println(returnExecute);\r
+        } finally {\r
+            setDirectory(origDirectory);\r
+        }\r
+    }\r
+\r
+    private File findGitDir() {\r
+        String gitPath = null;\r
+        if (getDirectory() != null) {\r
+            // org.eclipse.jgit.pgm.Main class does not use findGitDir(file). So it does not lookup upward.\r
+            gitPath = getDirectory();\r
+            while (gitPath != null) {\r
+                File f = new File(gitPath + File.separator + ".git");\r
+                if (f.exists() && f.isDirectory())\r
+                    return f;\r
+                gitPath = new File(gitPath).getParent();\r
+            }\r
+        }\r
+        return null;\r
+    }\r
+\r
+    public String getDirectory() {\r
+        return gitdir;\r
+    }\r
+\r
+    public void setDirectory(String gitdir) {\r
+        this.gitdir = gitdir;\r
+    }\r
+\r
+    public String getCommand() {\r
+        return command;\r
+    }\r
+\r
+    public void setCommand(String command) {\r
+        this.command = command;\r
+    }\r
+}\r
diff --git a/org.tizen.common.ui/src/org/tizen/common/ui/commandbar/command/git/ResetCommand.java b/org.tizen.common.ui/src/org/tizen/common/ui/commandbar/command/git/ResetCommand.java
new file mode 100644 (file)
index 0000000..ad546cd
--- /dev/null
@@ -0,0 +1,54 @@
+/*\r
+ * Common\r
+ *\r
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
+ *\r
+ * Contact:\r
+ * Changhyun Lee <changhyun1.lee@samsung.com>\r
+ * Hyeongseok Heo <hyeongseok.heo@samsung.com>\r
+ * BonYong Lee <bonyong.lee@samsung.com>\r
+ * Kangho Kim <kh5325.kim@samsung.com>\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ * Contributors:\r
+ * - S-Core Co., Ltd\r
+ *\r
+ */\r
+\r
+package org.tizen.common.ui.commandbar.command.git;\r
+\r
+import org.eclipse.jgit.api.Git;\r
+import org.eclipse.jgit.dircache.DirCache;\r
+import org.eclipse.jgit.lib.Constants;\r
+import org.eclipse.jgit.lib.Ref;\r
+import org.eclipse.jgit.lib.Repository;\r
+import org.tizen.common.ui.commandbar.command.launcher.CommandLauncher;\r
+\r
+public class ResetCommand extends Command {\r
+    protected void run(Repository repository) throws Exception {\r
+        if (repository != null) {\r
+            Git git = new Git(repository);\r
+\r
+            String[] args = (String[]) getContextValue(CommandLauncher.CONTEXT_ARGS);\r
+            if (args.length == 1) {\r
+                print("Unstaged changes after reset:\n");\r
+                // TODO:\r
+                return;\r
+            }\r
+\r
+            String paths = args[1];\r
+            git.reset().setRef(Constants.HEAD).addPath(paths).call();\r
+        }\r
+    }\r
+}\r
diff --git a/org.tizen.common.ui/src/org/tizen/common/ui/commandbar/command/git/RmCommand.java b/org.tizen.common.ui/src/org/tizen/common/ui/commandbar/command/git/RmCommand.java
new file mode 100644 (file)
index 0000000..900c220
--- /dev/null
@@ -0,0 +1,50 @@
+/*\r
+ * Common\r
+ *\r
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
+ *\r
+ * Contact:\r
+ * Changhyun Lee <changhyun1.lee@samsung.com>\r
+ * Hyeongseok Heo <hyeongseok.heo@samsung.com>\r
+ * BonYong Lee <bonyong.lee@samsung.com>\r
+ * Kangho Kim <kh5325.kim@samsung.com>\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ * Contributors:\r
+ * - S-Core Co., Ltd\r
+ *\r
+ */\r
+\r
+package org.tizen.common.ui.commandbar.command.git;\r
+\r
+import org.eclipse.jgit.api.Git;\r
+import org.eclipse.jgit.dircache.DirCache;\r
+import org.eclipse.jgit.lib.Repository;\r
+import org.tizen.common.ui.commandbar.command.launcher.CommandLauncher;\r
+\r
+public class RmCommand extends Command {\r
+    protected void run(Repository repository) throws Exception {\r
+        if (repository != null) {\r
+            Git git = new Git(repository);\r
+\r
+            String[] args = (String[]) getContextValue(CommandLauncher.CONTEXT_ARGS);\r
+            if (args.length == 1) {\r
+                return;\r
+            }\r
+\r
+            String paths = args[1];\r
+            DirCache dirCache = git.rm().addFilepattern(paths).call();\r
+        }\r
+    }\r
+}\r
diff --git a/org.tizen.common.ui/src/org/tizen/common/ui/commandbar/command/git/StatusCommand.java b/org.tizen.common.ui/src/org/tizen/common/ui/commandbar/command/git/StatusCommand.java
new file mode 100644 (file)
index 0000000..96f9260
--- /dev/null
@@ -0,0 +1,400 @@
+/*\r
+ * Common\r
+ *\r
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
+ *\r
+ * Contact:\r
+ * Changhyun Lee <changhyun1.lee@samsung.com>\r
+ * Hyeongseok Heo <hyeongseok.heo@samsung.com>\r
+ * BonYong Lee <bonyong.lee@samsung.com>\r
+ * Kangho Kim <kh5325.kim@samsung.com>\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ * Contributors:\r
+ * - S-Core Co., Ltd\r
+ *\r
+ */\r
+\r
+package org.tizen.common.ui.commandbar.command.git;\r
+\r
+import static org.eclipse.jgit.lib.Constants.HEAD;\r
+\r
+import java.io.IOException;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.eclipse.jgit.api.Git;\r
+import org.eclipse.jgit.diff.DiffEntry;\r
+import org.eclipse.jgit.diff.RenameDetector;\r
+import org.eclipse.jgit.lib.ObjectId;\r
+import org.eclipse.jgit.lib.Repository;\r
+import org.eclipse.jgit.lib.RepositoryState;\r
+import org.eclipse.jgit.revwalk.RevCommit;\r
+import org.eclipse.jgit.revwalk.RevWalk;\r
+import org.eclipse.jgit.treewalk.FileTreeIterator;\r
+import org.eclipse.jgit.treewalk.TreeWalk;\r
+\r
+public class StatusCommand extends Command {\r
+    private static final char DIFF_STATUS_ADDED = 'A';\r
+    private static final char DIFF_STATUS_COPIED = 'C';\r
+    private static final char DIFF_STATUS_DELETED = 'D';\r
+    private static final char DIFF_STATUS_MODIFIED = 'M';\r
+    private static final char DIFF_STATUS_RENAMED = 'R';\r
+    private static final char DIFF_STATUS_TYPE_CHANGED = 'T';\r
+    private static final char DIFF_STATUS_UNKNOWN = 'X';\r
+    private static final char DIFF_STATUS_UNMERGED = 'U';\r
+\r
+    private static final int WT_STATUS_UPDATED = 1;\r
+    private static final int WT_STATUS_CHANGED = 2;\r
+\r
+    protected void run(Repository repository) throws Exception {\r
+        if (repository != null) {\r
+            Git git = new Git(repository);\r
+            WorkingTreeStatus s = new WorkingTreeStatus(git.status().call());\r
+\r
+            prepare(repository, s);\r
+\r
+            print(repository, s);\r
+        }\r
+    }\r
+\r
+    private void print(Repository repository, WorkingTreeStatus s) {\r
+        printStatus(String.format("On branch %s\n", s.branch));\r
+        //wt_status_print_state(s, &state);\r
+        //wt_status_print_updated(s);\r
+        //wt_status_print_unmerged(s);\r
+        //wt_status_print_changed(s);\r
+        printState(s, repository.getRepositoryState());\r
+        //if (!s.is_initial)\r
+        printTracking(s);\r
+\r
+        printUpdated(s);\r
+        printChanged(s);\r
+        printOther(s, s.untracked, "Untracked files", "add");\r
+\r
+        if (!s.commitable) {\r
+            if (s.workdir_dirty) {\r
+                print("no changes added to commit (use \"git add\" and/or \"git commit -a\")\n");\r
+            }\r
+            else if (!s.untracked.isEmpty()) {\r
+                print("nothing added to commit but untracked files present (use \"git add\" to track)\n");\r
+            }\r
+            else {\r
+                print("nothing to commit, working directory clean\n");\r
+            }\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Currently not used since compute can be very long running.\r
+     *\r
+     * <p>Please see <a href="http://dev.eclipse.org/mhonarc/lists/jgit-dev/msg00426.html">http://dev.eclipse.org/mhonarc/lists/jgit-dev/msg00426.html</a>.\r
+     *\r
+     * @param repository\r
+     * @throws Exception\r
+     */\r
+    private void createRenameDetector(Repository repository) throws Exception {\r
+        TreeWalk tw = new TreeWalk(repository);\r
+        tw.setRecursive(true);\r
+        tw.addTree(getHead(repository).getTree());\r
+        tw.addTree(new FileTreeIterator(repository));\r
+\r
+        RenameDetector rd = new RenameDetector(repository);\r
+        rd.addAll(DiffEntry.scan(tw));\r
+\r
+        List<DiffEntry> lde = rd.compute(tw.getObjectReader(), null);\r
+        for (DiffEntry de : lde) {\r
+            if (de.getScore() >= rd.getRenameScore()) {\r
+                System.out.println("file: " + de.getOldPath() + " copied/moved to: " + de.getNewPath());\r
+            }\r
+        }\r
+    }\r
+\r
+    // from gitective\r
+    private static RevCommit getHead(final Repository repository) {\r
+        return getCommit(repository, HEAD);\r
+    }\r
+\r
+    // from gitective\r
+    private static RevCommit getCommit(final Repository repository, final String revision) {\r
+        if (repository == null)\r
+            throw new IllegalArgumentException("Repository can not be null");\r
+        if (revision == null)\r
+            throw new IllegalArgumentException("Revision can not be null");\r
+        if (revision.length() == 0)\r
+            throw new IllegalArgumentException("Revision can not be empty");\r
+\r
+        return parse(repository, resolve(repository, revision));\r
+    }\r
+\r
+    private static ObjectId resolve(final Repository repository, final String revision) {\r
+        try {\r
+            return repository.resolve(revision);\r
+        } catch (IOException e) {\r
+            throw new RuntimeException(e);\r
+        }\r
+    }\r
+\r
+    private static RevCommit parse(final Repository repository, final ObjectId commit) {\r
+        final RevWalk walk = new RevWalk(repository);\r
+        walk.setRetainBody(true);\r
+        try {\r
+            return walk.parseCommit(commit);\r
+        } catch (IOException e) {\r
+            throw new RuntimeException(e);\r
+        } finally {\r
+            walk.release();\r
+        }\r
+    }\r
+\r
+    private void printState(WorkingTreeStatus s, RepositoryState state) {\r
+        if (state == RepositoryState.MERGING) {\r
+            printlnStatus("merging");\r
+        }\r
+        else if (state == RepositoryState.REBASING || state == RepositoryState.REBASING_INTERACTIVE) {\r
+            printlnStatus("rebasing");\r
+        }\r
+        else if (state == RepositoryState.CHERRY_PICKING) {\r
+            printlnStatus("cherry_picking");\r
+        }\r
+        else if (state == RepositoryState.REVERTING) {\r
+            printlnStatus("reverting");\r
+        }\r
+        if (state == RepositoryState.BISECTING) {\r
+            printlnStatus("bisecting");\r
+        }\r
+    }\r
+\r
+    private void printTracking(WorkingTreeStatus s) {\r
+    }\r
+\r
+    /**\r
+     * -1 : has delete\r
+     * 0 : no change\r
+     * 1 : some change but no delete\r
+     */\r
+    private int checkWorktreeChanges(WorkingTreeStatus s) {\r
+        int changes = 0;\r
+\r
+        for (ListItem it : s.change) {\r
+            WorkingTreeStatusChangeData d = it.util;\r
+            if (d.worktree_status == 0 || d.worktree_status == DIFF_STATUS_UNMERGED)\r
+                continue;\r
+            if (changes == 0)\r
+                changes = 1;\r
+            // rm (not staged)\r
+            if (d.worktree_status == DIFF_STATUS_DELETED)\r
+                changes = -1;\r
+        }\r
+        return changes;\r
+    }\r
+\r
+    private void printUpdated(WorkingTreeStatus s) {\r
+        boolean shown_header = false;\r
+\r
+        // git rm, git add -> Changes to be committed:\r
+        for (ListItem it : s.change) {\r
+            WorkingTreeStatusChangeData d = it.util;\r
+            if (d.index_status == 0 || d.index_status == DIFF_STATUS_UNMERGED)\r
+                continue;\r
+            if (!shown_header) {\r
+                printCachedHeader(s);\r
+                s.commitable = true;\r
+                shown_header = true;\r
+            }\r
+            printChangeData(s, WT_STATUS_UPDATED, it);\r
+        }\r
+        if (shown_header)\r
+            printTrailer(s);\r
+    }\r
+\r
+    private void printCachedHeader(WorkingTreeStatus s) {\r
+        printlnStatus("Changes to be committed:");\r
+        printlnStatus(String.format("  (use \"git reset %s <file>...\" to unstage)", s.reference));\r
+        printlnStatus("");\r
+    }\r
+\r
+    private void printChanged(WorkingTreeStatus s) {\r
+        int worktree_changes = checkWorktreeChanges(s);\r
+\r
+        if (worktree_changes == 0)\r
+            return;\r
+\r
+        printDirtyHeader(s, worktree_changes < 0);\r
+\r
+        for (ListItem it : s.change) {\r
+            WorkingTreeStatusChangeData d = it.util;\r
+            if (d.worktree_status == 0 || d.worktree_status == DIFF_STATUS_UNMERGED)\r
+                continue;\r
+            printChangeData(s, WT_STATUS_CHANGED, it);\r
+        }\r
+        printTrailer(s);\r
+    }\r
+\r
+    private void printChangeData(WorkingTreeStatus s, int change_type, ListItem it) {\r
+        WorkingTreeStatusChangeData d = it.util;\r
+        int status = 0;\r
+        String one;\r
+\r
+        switch (change_type) {\r
+        case WT_STATUS_UPDATED:\r
+            status = d.index_status;\r
+            break;\r
+        case WT_STATUS_CHANGED:\r
+            // TODO: submodule\r
+            status = d.worktree_status;\r
+            break;\r
+        default:\r
+            break;\r
+        }\r
+\r
+        // TODO: Make relative by quote_path\r
+        one = it.path;\r
+\r
+        printStatus("\t");\r
+        switch (status) {\r
+        case DIFF_STATUS_ADDED:\r
+            printStatusMore(String.format("new file:   %s", one));\r
+            break;\r
+        case DIFF_STATUS_DELETED:\r
+            printStatusMore(String.format("deleted:    %s", one));\r
+            break;\r
+        case DIFF_STATUS_MODIFIED:\r
+            printStatusMore(String.format("modified:   %s", one));\r
+            break;\r
+        case DIFF_STATUS_RENAMED:\r
+            // TODO: Not supported\r
+            // If we call createRenameDetector(), rename can be detected. But compute can be very long running.\r
+            //  cf.)) http://stackoverflow.com/questions/17296278/jgit-detect-rename-in-working-copy/17302068\r
+            printStatusMore(String.format("renamed:   %s -> %s", one));\r
+            break;\r
+        }\r
+        printStatusMore("\n");\r
+    }\r
+\r
+    private void printOther(WorkingTreeStatus s, List<ListItem> l, String what, String how) {\r
+        if (l.isEmpty())\r
+            return;\r
+\r
+        printOtherHeader(s, what, how);\r
+\r
+        for (ListItem it : l) {\r
+            printStatus(String.format("\t%s\n", it.path));\r
+        }\r
+    }\r
+\r
+    private void printOtherHeader(WorkingTreeStatus s, String what, String how) {\r
+        printlnStatus(String.format("%s:", what));\r
+        printlnStatus(String.format("  (use \"git %s <file>...\" to include in what will be committed)", how));\r
+        printlnStatus("");\r
+    }\r
+\r
+    private void printDirtyHeader(WorkingTreeStatus s, boolean hasDeleted) {\r
+        printlnStatus("Changes not staged for commit:");\r
+        if (!hasDeleted)\r
+            printlnStatus("  (use \"git add <file>...\" to update what will be committed)");\r
+        else\r
+            printlnStatus("  (use \"git add/rm <file>...\" to update what will be committed)");\r
+        printlnStatus("  (use \"git checkout -- <file>...\" to discard changes in working directory)");\r
+        //print("  (commit or discard the untracked or modified content in submodules)");\r
+        printlnStatus("");\r
+    }\r
+\r
+    private void prepare(Repository repository, WorkingTreeStatus s) {\r
+        try {\r
+            s.branch = repository.getBranch();\r
+        } catch (IOException e) {\r
+        }\r
+        s.reference = "HEAD";\r
+    }\r
+\r
+    private void printTrailer(WorkingTreeStatus s) {\r
+        printlnStatus("");\r
+    }\r
+\r
+    private void printlnStatus(String line) {\r
+        getConsole().println("# " + line);\r
+    }\r
+\r
+    private void printStatus(String line) {\r
+        getConsole().print("# " + line);\r
+    }\r
+\r
+    private void printStatusMore(String line) {\r
+        getConsole().print(line);\r
+    }\r
+\r
+    class WorkingTreeStatus {\r
+        org.eclipse.jgit.api.Status status;\r
+\r
+        String branch;\r
+        String reference;\r
+\r
+        boolean commitable;\r
+        boolean workdir_dirty;\r
+        List<ListItem> change;\r
+        List<ListItem> untracked;\r
+\r
+        public WorkingTreeStatus(org.eclipse.jgit.api.Status status) {\r
+            this.status = status;\r
+            try {\r
+                workdir_dirty = !status.isClean();\r
+                change = new ArrayList<ListItem>();\r
+                for (String path : status.getAdded()) {\r
+                    change.add(new ListItem(path, new WorkingTreeStatusChangeData(0, DIFF_STATUS_ADDED)));\r
+                }\r
+                for (String path : status.getRemoved()) {\r
+                    change.add(new ListItem(path, new WorkingTreeStatusChangeData(0, DIFF_STATUS_DELETED)));\r
+                }\r
+                // if you modify an existing file and call 'git add ...' on it\r
+                for (String path : status.getChanged()) {\r
+                    change.add(new ListItem(path, new WorkingTreeStatusChangeData(0, DIFF_STATUS_MODIFIED)));\r
+                }\r
+                for (String path : status.getModified()) {\r
+                    change.add(new ListItem(path, new WorkingTreeStatusChangeData(DIFF_STATUS_MODIFIED, 0)));\r
+                    //workdir_dirty = true;\r
+                }\r
+                for (String path : status.getMissing()) {\r
+                    change.add(new ListItem(path, new WorkingTreeStatusChangeData(DIFF_STATUS_DELETED, 0)));\r
+                }\r
+                untracked = new ArrayList<ListItem>();\r
+                for (String path : status.getUntracked()) {\r
+                    untracked.add(new ListItem(path, new WorkingTreeStatusChangeData(0, 0)));\r
+                }\r
+                // TODO: status.getConflicting()\r
+            } catch (Exception e) {\r
+            }\r
+        }\r
+    }\r
+\r
+    class WorkingTreeStatusChangeData {\r
+        int worktree_status;\r
+        int index_status;\r
+\r
+        public WorkingTreeStatusChangeData(int worktree_status, int index_status) {\r
+            this.worktree_status = worktree_status;\r
+            this.index_status = index_status;\r
+        }\r
+    }\r
+\r
+    class ListItem {\r
+        String path;\r
+        WorkingTreeStatusChangeData util;\r
+\r
+        public ListItem(String path, WorkingTreeStatusChangeData util) {\r
+            this.path = path;\r
+            this.util = util;\r
+        }\r
+    }\r
+}\r
index 3b67d51..ff953bd 100644 (file)
@@ -174,6 +174,7 @@ public class CommandLauncher extends AbstractLauncher {
         // TODO: need to use custom OptionValidator?\r
         // opt contains illegal character value '@'\r
         //result.addOption(OptionBuilder.hasArg(true).create("@q"));\r
+        addOption(result, OptionBuilder.hasArg(true).create(Commands.GIT_COMMAND), new GitCommand());\r
         addOption(result, OptionBuilder.hasArg(true).create(Commands.QUERY_COMMAND), new QueryCommand());\r
         result.addOption(OptionBuilder.hasArg(true).create(Commands.SHOW_COMMAND));\r
         addOption(result, OptionBuilder.hasArg(true).create(Commands.SDB_COMMAND), new SdbCommand());\r