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 c69304243449f881f0601d327dbbe93a0a80b58e..d4d4f5412fc7894a863c139b6c73f0d1048880c1 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java
@@ -1,4 +1,5 @@
 /*
+ * Copyright (C) 2008-2010, Google Inc.
  * Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com>
  * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
  * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
@@ -46,6 +47,7 @@
 package org.eclipse.jgit.transport;
 
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.PipedInputStream;
 import java.io.PipedOutputStream;
@@ -142,15 +144,13 @@ private String commandFor(final String exe) {
 		return cmd.toString();
 	}
 
-	ChannelExec exec(final String exe, final OutputStream err)
-			throws TransportException {
+	ChannelExec exec(final String exe) throws TransportException {
 		initSession();
 
 		final int tms = getTimeout() > 0 ? getTimeout() * 1000 : 0;
 		try {
 			final ChannelExec channel = (ChannelExec) sock.openChannel("exec");
 			channel.setCommand(commandFor(exe));
-			channel.setErrStream(err);
 			channel.connect(tms);
 			return channel;
 		} catch (JSchException je) {
@@ -224,6 +224,8 @@ public void close() throws IOException {
 	class SshFetchConnection extends BasePackFetchConnection {
 		private ChannelExec channel;
 
+		private Thread errorThread;
+
 		private int exitStatus;
 
 		SshFetchConnection() throws TransportException {
@@ -231,12 +233,16 @@ class SshFetchConnection extends BasePackFetchConnection {
 			try {
 				final MessageWriter msg = new MessageWriter();
 				setMessageWriter(msg);
-				channel = exec(getOptionUploadPack(), msg.getRawStream());
 
-				if (channel.isConnected())
-					init(channel.getInputStream(), outputStream(channel));
-				else
-					throw new TransportException(uri, getMessages());
+				channel = exec(getOptionUploadPack());
+				if (!channel.isConnected())
+					throw new TransportException(uri, "connection failed");
+
+				final InputStream upErr = channel.getErrStream();
+				errorThread = new StreamCopyThread(upErr, msg.getRawStream());
+				errorThread.start();
+
+				init(channel.getInputStream(), outputStream(channel));
 
 			} catch (TransportException err) {
 				close();
@@ -258,6 +264,16 @@ class SshFetchConnection extends BasePackFetchConnection {
 
 		@Override
 		public void close() {
+			if (errorThread != null) {
+				try {
+					errorThread.join();
+				} catch (InterruptedException e) {
+					// Stop waiting and return anyway.
+				} finally {
+					errorThread = null;
+				}
+			}
+
 			super.close();
 
 			if (channel != null) {
@@ -275,6 +291,8 @@ public void close() {
 	class SshPushConnection extends BasePackPushConnection {
 		private ChannelExec channel;
 
+		private Thread errorThread;
+
 		private int exitStatus;
 
 		SshPushConnection() throws TransportException {
@@ -282,12 +300,16 @@ class SshPushConnection extends BasePackPushConnection {
 			try {
 				final MessageWriter msg = new MessageWriter();
 				setMessageWriter(msg);
-				channel = exec(getOptionReceivePack(), msg.getRawStream());
 
-				if (channel.isConnected())
-					init(channel.getInputStream(), outputStream(channel));
-				else
-					throw new TransportException(uri, getMessages());
+				channel = exec(getOptionReceivePack());
+				if (!channel.isConnected())
+					throw new TransportException(uri, "connection failed");
+
+				final InputStream rpErr = channel.getErrStream();
+				errorThread = new StreamCopyThread(rpErr, msg.getRawStream());
+				errorThread.start();
+
+				init(channel.getInputStream(), outputStream(channel));
 
 			} catch (TransportException err) {
 				close();
@@ -309,6 +331,16 @@ class SshPushConnection extends BasePackPushConnection {
 
 		@Override
 		public void close() {
+			if (errorThread != null) {
+				try {
+					errorThread.join();
+				} catch (InterruptedException e) {
+					// Stop waiting and return anyway.
+				} finally {
+					errorThread = null;
+				}
+			}
+
 			super.close();
 
 			if (channel != null) {