diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportLocal.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportLocal.java index c9b18be1f..3ede748b3 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportLocal.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportLocal.java @@ -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 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); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java index 87d5395bf..8faefede1 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java @@ -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); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java index 0ebf2e307..e69596313 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java @@ -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 argv = new ArrayList(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() { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java index 0ee7a6bc5..0e05de091 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32.java @@ -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 argv = new ArrayList(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; + } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32_Cygwin.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32_Cygwin.java index 15da505f5..4e8841c99 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32_Cygwin.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_Win32_Cygwin.java @@ -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 argv = new ArrayList(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; + } }