]> source.dussan.org Git - jgit.git/commitdiff
Fix JGit --upload-pack, --receive-pack options 16/2416/4
authorShawn O. Pearce <spearce@spearce.org>
Fri, 4 Feb 2011 13:51:27 +0000 (05:51 -0800)
committerShawn O. Pearce <spearce@spearce.org>
Sun, 6 Feb 2011 01:40:54 +0000 (17:40 -0800)
JGit did not use sh -c to run the receive-pack or upload-pack programs
locally, which caused errors if these strings contained spaces and
needed the local shell to evaluate them.

Win32 support using cmd.exe /c is completely untested, but seems like
it should work based on the limited information I could get through
Google search results.

Bug: 336301
Change-Id: I22e5e3492fdebbae092d1ce6b47ad411e57cc1ba
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportLocal.java
org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java
org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java
org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32_Cygwin.java

index c9b18be1f8ab7685689406c5284ab4e4c831313c..3ede748b340d2b9c5fb3cc300d9fe83afb56a7e0 100644 (file)
@@ -55,6 +55,7 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.PipedInputStream;
 import java.io.PipedOutputStream;
+import java.util.Map;
 
 import org.eclipse.jgit.JGitText;
 import org.eclipse.jgit.errors.NotSupportedException;
@@ -146,22 +147,22 @@ class TransportLocal extends Transport implements PackTransport {
        protected Process spawn(final String cmd)
                        throws TransportException {
                try {
-                       final String[] args;
-
-                       if (cmd.startsWith("git-")) {
-                               args = new String[] { "git", cmd.substring(4), PWD };
-                       } else {
-                               final int gitspace = cmd.indexOf("git ");
-                               if (gitspace >= 0) {
-                                       final String git = cmd.substring(0, gitspace + 3);
-                                       final String subcmd = cmd.substring(gitspace + 4);
-                                       args = new String[] { git, subcmd, PWD };
-                               } else {
-                                       args = new String[] { cmd, PWD };
-                               }
-                       }
-
-                       return Runtime.getRuntime().exec(args, null, remoteGitDir);
+                       String[] args = { "." };
+                       ProcessBuilder proc = local.getFS().runInShell(cmd, args);
+                       proc.directory(remoteGitDir);
+
+                       // Remove the same variables CGit does.
+                       Map<String, String> env = proc.environment();
+                       env.remove("GIT_ALTERNATE_OBJECT_DIRECTORIES");
+                       env.remove("GIT_CONFIG");
+                       env.remove("GIT_CONFIG_PARAMETERS");
+                       env.remove("GIT_DIR");
+                       env.remove("GIT_WORK_TREE");
+                       env.remove("GIT_GRAFT_FILE");
+                       env.remove("GIT_INDEX_FILE");
+                       env.remove("GIT_NO_REPLACE_OBJECTS");
+
+                       return proc.start();
                } catch (IOException err) {
                        throw new TransportException(uri, err.getMessage(), err);
                }
index 87d5395bf9ed2b9c7a74a6b609b283bebb69dd28..8faefede1c2313ef2a3ea5132868f4c91fff2ed1 100644 (file)
@@ -255,4 +255,18 @@ public abstract class FS {
 
        /** @return the $prefix directory C Git would use. */
        public abstract File gitPrefix();
+
+       /**
+        * Initialize a ProcesssBuilder to run a command using the system shell.
+        *
+        * @param cmd
+        *            command to execute. This string should originate from the
+        *            end-user, and thus is platform specific.
+        * @param args
+        *            arguments to pass to command. These should be protected from
+        *            shell evaluation.
+        * @return a partially completed process builder. Caller should finish
+        *         populating directory, environment, and then start the process.
+        */
+       public abstract ProcessBuilder runInShell(String cmd, String[] args);
 }
index 0ebf2e307b57ab33d7208bce2c77a0fd81bb514a..e69596313628d1b07f93d7393a577608d5165489 100644 (file)
@@ -46,6 +46,9 @@ import java.io.File;
 import java.nio.charset.Charset;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 
 abstract class FS_POSIX extends FS {
        @Override
@@ -69,6 +72,19 @@ abstract class FS_POSIX extends FS {
                return null;
        }
 
+       @Override
+       public ProcessBuilder runInShell(String cmd, String[] args) {
+               List<String> argv = new ArrayList<String>(4 + args.length);
+               argv.add("sh");
+               argv.add("-c");
+               argv.add(cmd + " \"$@\"");
+               argv.add(cmd);
+               argv.addAll(Arrays.asList(args));
+               ProcessBuilder proc = new ProcessBuilder();
+               proc.command(argv);
+               return proc;
+       }
+
        private static boolean isMacOS() {
                final String osDotName = AccessController
                                .doPrivileged(new PrivilegedAction<String>() {
index 0ee7a6bc50e6d6fe0f233e88539ef86b67f65df9..0e05de09164dd145823f861c092a4c787aebb11a 100644 (file)
@@ -48,6 +48,9 @@ import java.io.File;
 import java.nio.charset.Charset;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 
 class FS_Win32 extends FS {
        static boolean detect() {
@@ -114,4 +117,16 @@ class FS_Win32 extends FS {
 
                return super.userHomeImpl();
        }
+
+       @Override
+       public ProcessBuilder runInShell(String cmd, String[] args) {
+               List<String> argv = new ArrayList<String>(3 + args.length);
+               argv.add("cmd.exe");
+               argv.add("/c");
+               argv.add(cmd);
+               argv.addAll(Arrays.asList(args));
+               ProcessBuilder proc = new ProcessBuilder();
+               proc.command(argv);
+               return proc;
+       }
 }
index 15da505f5da042be2cb837f1ce5f2389de6bc587..4e8841c9901c9b31fde36c32f51f0cab7a996718 100644 (file)
@@ -46,6 +46,9 @@ package org.eclipse.jgit.util;
 import java.io.File;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 
 class FS_Win32_Cygwin extends FS_Win32 {
        private static String cygpath;
@@ -86,4 +89,17 @@ class FS_Win32_Cygwin extends FS_Win32 {
                        return super.userHomeImpl();
                return resolve(new File("."), home);
        }
+
+       @Override
+       public ProcessBuilder runInShell(String cmd, String[] args) {
+               List<String> argv = new ArrayList<String>(4 + args.length);
+               argv.add("sh.exe");
+               argv.add("-c");
+               argv.add(cmd + " \"$@\"");
+               argv.add(cmd);
+               argv.addAll(Arrays.asList(args));
+               ProcessBuilder proc = new ProcessBuilder();
+               proc.command(argv);
+               return proc;
+       }
 }