diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java
index 2603ca2879411f549a5cadc14bba47d39eb24495..6e8b05da23c8da0c9a28bd2e140b29786f566fab 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java
@@ -86,6 +86,8 @@ class BasePackPushConnection extends BasePackConnection implements
 
 	static final String CAPABILITY_OFS_DELTA = "ofs-delta";
 
+	static final String CAPABILITY_SIDE_BAND_64K = "side-band-64k";
+
 	private final boolean thinPack;
 
 	private boolean capableDeleteRefs;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java
index 4d63ee68ef5c4f0799b5a740235e421270d693c1..c5bbdac5a32ea6c3660c7acde0eaf9ff9d3d6075 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java
@@ -43,13 +43,20 @@
 
 package org.eclipse.jgit.transport;
 
-import java.io.BufferedWriter;
+import static org.eclipse.jgit.transport.BasePackPushConnection.CAPABILITY_DELETE_REFS;
+import static org.eclipse.jgit.transport.BasePackPushConnection.CAPABILITY_OFS_DELTA;
+import static org.eclipse.jgit.transport.BasePackPushConnection.CAPABILITY_REPORT_STATUS;
+import static org.eclipse.jgit.transport.BasePackPushConnection.CAPABILITY_SIDE_BAND_64K;
+import static org.eclipse.jgit.transport.SideBandOutputStream.CH_DATA;
+import static org.eclipse.jgit.transport.SideBandOutputStream.CH_PROGRESS;
+import static org.eclipse.jgit.transport.SideBandOutputStream.MAX_BUF;
+
 import java.io.EOFException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
+import java.io.Writer;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashSet;
@@ -84,12 +91,6 @@
  * Implements the server side of a push connection, receiving objects.
  */
 public class ReceivePack {
-	static final String CAPABILITY_REPORT_STATUS = BasePackPushConnection.CAPABILITY_REPORT_STATUS;
-
-	static final String CAPABILITY_DELETE_REFS = BasePackPushConnection.CAPABILITY_DELETE_REFS;
-
-	static final String CAPABILITY_OFS_DELTA = BasePackPushConnection.CAPABILITY_OFS_DELTA;
-
 	/** Database we write the stored objects into. */
 	private final Repository db;
 
@@ -151,7 +152,7 @@ public class ReceivePack {
 
 	private PacketLineOut pckOut;
 
-	private PrintWriter msgs;
+	private Writer msgs;
 
 	/** The refs we advertised as existing at the start of the connection. */
 	private Map<String, Ref> refs;
@@ -165,9 +166,12 @@ public class ReceivePack {
 	/** An exception caught while unpacking and fsck'ing the objects. */
 	private Throwable unpackError;
 
-	/** if {@link #enabledCapablities} has {@link #CAPABILITY_REPORT_STATUS} */
+	/** If {@link BasePackPushConnection#CAPABILITY_REPORT_STATUS} is enabled. */
 	private boolean reportStatus;
 
+	/** If {@link BasePackPushConnection#CAPABILITY_SIDE_BAND_64K} is enabled. */
+	private boolean sideBand;
+
 	/** Lock around the received pack file, while updating refs. */
 	private PackLock packLock;
 
@@ -440,7 +444,12 @@ public List<ReceiveCommand> getAllCommands() {
 	 *            string must not end with an LF, and must not contain an LF.
 	 */
 	public void sendError(final String what) {
-		sendMessage("error", what);
+		try {
+			if (msgs != null)
+				msgs.write("error: " + what + "\n");
+		} catch (IOException e) {
+			// Ignore write failures.
+		}
 	}
 
 	/**
@@ -454,12 +463,12 @@ public void sendError(final String what) {
 	 *            string must not end with an LF, and must not contain an LF.
 	 */
 	public void sendMessage(final String what) {
-		sendMessage("remote", what);
-	}
-
-	private void sendMessage(final String type, final String what) {
-		if (msgs != null)
-			msgs.println(type + ": " + what);
+		try {
+			if (msgs != null)
+				msgs.write(what + "\n");
+		} catch (IOException e) {
+			// Ignore write failures.
+		}
 	}
 
 	/**
@@ -499,16 +508,8 @@ public void receive(final InputStream input, final OutputStream output,
 
 			pckIn = new PacketLineIn(rawIn);
 			pckOut = new PacketLineOut(rawOut);
-			if (messages != null) {
-				msgs = new PrintWriter(new BufferedWriter(
-						new OutputStreamWriter(messages, Constants.CHARSET),
-						8192)) {
-					@Override
-					public void println() {
-						print('\n');
-					}
-				};
-			}
+			if (messages != null)
+				msgs = new OutputStreamWriter(messages, Constants.CHARSET);
 
 			enabledCapablities = new HashSet<String>();
 			commands = new ArrayList<ReceiveCommand>();
@@ -516,8 +517,19 @@ public void println() {
 			service();
 		} finally {
 			try {
-				if (msgs != null) {
+				if (pckOut != null)
+					pckOut.flush();
+				if (msgs != null)
 					msgs.flush();
+
+				if (sideBand) {
+					// If we are using side band, we need to send a final
+					// flush-pkt to tell the remote peer the side band is
+					// complete and it should stop decoding. We need to
+					// use the original output stream as rawOut is now the
+					// side band data channel.
+					//
+					new PacketLineOut(output).end();
 				}
 			} finally {
 				unlockPack();
@@ -581,10 +593,9 @@ void sendString(final String s) throws IOException {
 			} else if (msgs != null) {
 				sendStatusReport(false, new Reporter() {
 					void sendString(final String s) throws IOException {
-						msgs.println(s);
+						msgs.write(s + "\n");
 					}
 				});
-				msgs.flush();
 			}
 
 			postReceive.onPostReceive(this, filterCommands(Result.OK));
@@ -609,6 +620,7 @@ private void unlockPack() {
 	public void sendAdvertisedRefs(final RefAdvertiser adv) throws IOException {
 		final RevFlag advertised = walk.newFlag("ADVERTISED");
 		adv.init(walk, advertised);
+		adv.advertiseCapability(CAPABILITY_SIDE_BAND_64K);
 		adv.advertiseCapability(CAPABILITY_DELETE_REFS);
 		adv.advertiseCapability(CAPABILITY_REPORT_STATUS);
 		if (allowOfsDelta)
@@ -667,6 +679,16 @@ private void recvCommands() throws IOException {
 
 	private void enableCapabilities() {
 		reportStatus = enabledCapablities.contains(CAPABILITY_REPORT_STATUS);
+
+		sideBand = enabledCapablities.contains(CAPABILITY_SIDE_BAND_64K);
+		if (sideBand) {
+			OutputStream out = rawOut;
+
+			rawOut = new SideBandOutputStream(CH_DATA, MAX_BUF, out);
+			pckOut = new PacketLineOut(rawOut);
+			msgs = new OutputStreamWriter(new SideBandOutputStream(CH_PROGRESS,
+					MAX_BUF, out), Constants.CHARSET);
+		}
 	}
 
 	private boolean needPack() {