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 d87395c1cd7380dcf03aadeb2ddace413f2b5789..4ba446edbe38f4b9fdf38f3a87a0b41645fe7891 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java
@@ -96,6 +96,19 @@ public class ReceivePack {
 	/** Revision traversal support over {@link #db}. */
 	private final RevWalk walk;
 
+	/**
+	 * Is the client connection a bi-directional socket or pipe?
+	 * <p>
+	 * If true, this class assumes it can perform multiple read and write cycles
+	 * with the client over the input and output streams. This matches the
+	 * functionality available with a standard TCP/IP connection, or a local
+	 * operating system or in-memory pipe.
+	 * <p>
+	 * If false, this class runs in a read everything then output results mode,
+	 * making it suitable for single round-trip systems RPCs such as HTTP.
+	 */
+	private boolean biDirectionalPipe = true;
+
 	/** Should an incoming transfer validate objects? */
 	private boolean checkReceivedObjects;
 
@@ -219,6 +232,27 @@ public final Map<String, Ref> getAdvertisedRefs() {
 		return refs;
 	}
 
+	/**
+	 * @return true if this class expects a bi-directional pipe opened between
+	 *         the client and itself. The default is true.
+	 */
+	public boolean isBiDirectionalPipe() {
+		return biDirectionalPipe;
+	}
+
+	/**
+	 * @param twoWay
+	 *            if true, this class will assume the socket is a fully
+	 *            bidirectional pipe between the two peers and takes advantage
+	 *            of that by first transmitting the known refs, then waiting to
+	 *            read commands. If false, this class assumes it must read the
+	 *            commands before writing output and does not perform the
+	 *            initial advertising.
+	 */
+	public void setBiDirectionalPipe(final boolean twoWay) {
+		biDirectionalPipe = twoWay;
+	}
+
 	/**
 	 * @return true if this instance will verify received objects are formatted
 	 *         correctly. Validating objects requires more CPU time on this side
@@ -484,7 +518,10 @@ public void println() {
 	}
 
 	private void service() throws IOException {
-		sendAdvertisedRefs();
+		if (biDirectionalPipe)
+			sendAdvertisedRefs();
+		else
+			refs = db.getAllRefs();
 		recvCommands();
 		if (!commands.isEmpty()) {
 			enableCapabilities();
@@ -587,7 +624,11 @@ private void recvCommands() throws IOException {
 			final ObjectId newId = ObjectId.fromString(line.substring(41, 81));
 			final String name = line.substring(82);
 			final ReceiveCommand cmd = new ReceiveCommand(oldId, newId, name);
-			cmd.setRef(refs.get(cmd.getRefName()));
+			if (name.equals(Constants.HEAD)) {
+				cmd.setResult(Result.REJECTED_CURRENT_BRANCH);
+			} else {
+				cmd.setRef(refs.get(cmd.getRefName()));
+			}
 			commands.add(cmd);
 		}
 	}