From 22e720ce772c3ccd27c56319d5f1e141a74a20ac Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Fri, 3 Dec 2010 16:33:46 -0800 Subject: [PATCH] Honor GIT_SSH when opening SSH connections If the environment variable GIT_SSH is set, use GIT_SSH for any remote protocol connections, instead of the local JSch library. Bug: 321062 Change-Id: Ia18ea49d58f3ed657430067f1f72ef788a2dae4c Signed-off-by: Shawn O. Pearce --- .../jgit/transport/TransportGitSsh.java | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java index bfe066dd9..8132ac3c3 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java @@ -52,12 +52,16 @@ import java.io.OutputStream; import java.io.PipedInputStream; import java.io.PipedOutputStream; import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.List; import org.eclipse.jgit.JGitText; import org.eclipse.jgit.errors.NoRemoteRepositoryException; import org.eclipse.jgit.errors.TransportException; +import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.util.QuotedString; +import org.eclipse.jgit.util.SystemReader; import org.eclipse.jgit.util.io.MessageWriter; import org.eclipse.jgit.util.io.StreamCopyThread; @@ -106,6 +110,8 @@ public class TransportGitSsh extends SshTransport implements PackTransport { } private Connection newConnection() { + if (useExtConnection()) + return new ExtConnection(); return new JschConnection(); } @@ -286,6 +292,89 @@ public class TransportGitSsh extends SshTransport implements PackTransport { } } + private static boolean useExtConnection() { + return SystemReader.getInstance().getenv("GIT_SSH") != null; + } + + private class ExtConnection extends Connection { + private Process proc; + + private int exitStatus; + + @Override + void exec(String commandName) throws TransportException { + String ssh = SystemReader.getInstance().getenv("GIT_SSH"); + boolean putty = ssh.toLowerCase().contains("plink"); + + List args = new ArrayList(); + args.add(ssh); + if (putty) + args.add("--batch"); + if (0 < getURI().getPort()) { + args.add(putty ? "-P" : "-p"); + args.add(String.valueOf(getURI().getPort())); + } + if (getURI().getUser() != null) + args.add(getURI().getUser() + "@" + getURI().getHost()); + else + args.add(getURI().getHost()); + args.add(commandFor(commandName)); + + ProcessBuilder pb = new ProcessBuilder(); + pb.command(args); + + if (local.getDirectory() != null) + pb.environment().put(Constants.GIT_DIR_KEY, + local.getDirectory().getPath()); + + try { + proc = pb.start(); + } catch (IOException err) { + throw new TransportException(uri, err.getMessage(), err); + } + } + + @Override + void connect() throws TransportException { + // Nothing to do, the process was already opened. + } + + @Override + InputStream getInputStream() throws IOException { + return proc.getInputStream(); + } + + @Override + OutputStream getOutputStream() throws IOException { + return proc.getOutputStream(); + } + + @Override + InputStream getErrorStream() throws IOException { + return proc.getErrorStream(); + } + + @Override + int getExitStatus() { + return exitStatus; + } + + @Override + void close() { + if (proc != null) { + try { + try { + exitStatus = proc.waitFor(); + } catch (InterruptedException e) { + // Ignore the interrupt, but return immediately. + } + } finally { + proc = null; + } + } + } + } + class SshFetchConnection extends BasePackFetchConnection { private Connection conn;