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>tags/v0.11.1
@@ -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); | |||
} |
@@ -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); | |||
} |
@@ -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>() { |
@@ -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; | |||
} | |||
} |
@@ -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; | |||
} | |||
} |