diff options
author | Shawn O. Pearce <spearce@spearce.org> | 2011-02-04 05:51:27 -0800 |
---|---|---|
committer | Shawn O. Pearce <spearce@spearce.org> | 2011-02-05 17:40:54 -0800 |
commit | c6423932bf466af76daf2cf38f37bc23cd16bf63 (patch) | |
tree | 2e68a05b6c0059cff6d4dd1bef96be634e2adce0 | |
parent | 78e61ea2519f0877c76216b57cf9554639383e70 (diff) | |
download | jgit-c6423932bf466af76daf2cf38f37bc23cd16bf63.tar.gz jgit-c6423932bf466af76daf2cf38f37bc23cd16bf63.zip |
Fix JGit --upload-pack, --receive-pack options
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>
5 files changed, 78 insertions, 16 deletions
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 c9b18be1f8..3ede748b34 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<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); } 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 87d5395bf9..8faefede1c 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 0ebf2e307b..e695963136 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<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>() { 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 0ee7a6bc50..0e05de0916 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<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; + } } 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 15da505f5d..4e8841c990 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<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; + } } |