From d5bc8be743a6308509f36a2bd2f9414030eea9ea Mon Sep 17 00:00:00 2001
From: "Shawn O. Pearce" <spearce@spearce.org>
Date: Mon, 4 Jan 2010 15:20:11 -0800
Subject: [PATCH] Download HEAD by itself if not in info/refs

The dumb HTTP transport needs to download the HEAD ref and
resolve it manually if HEAD does not appear in info/refs.

Its typically for it to not be in the info/refs file.

Change-Id: Ie2a58fdfacfeee530b10edb433b8f98c85568585
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
 .../eclipse/jgit/transport/TransportHttp.java | 69 ++++++++++++++++---
 1 file changed, 59 insertions(+), 10 deletions(-)

diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java
index b9dfd1c0e..62303de9f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java
@@ -187,16 +187,7 @@ public FetchConnection openFetch() throws TransportException,
 					// Assume this server doesn't support smart HTTP fetch
 					// and fall back on dumb object walking.
 					//
-					HttpObjectDB d = new HttpObjectDB(objectsUrl);
-					WalkFetchConnection wfc = new WalkFetchConnection(this, d);
-					BufferedReader br = new BufferedReader(
-							new InputStreamReader(in, Constants.CHARSET));
-					try {
-						wfc.available(d.readAdvertisedImpl(br));
-					} finally {
-						br.close();
-					}
-					return wfc;
+					return newDumbConnection(in);
 				}
 			} finally {
 				in.close();
@@ -210,6 +201,64 @@ public FetchConnection openFetch() throws TransportException,
 		}
 	}
 
+	private FetchConnection newDumbConnection(InputStream in)
+			throws IOException, PackProtocolException {
+		HttpObjectDB d = new HttpObjectDB(objectsUrl);
+		BufferedReader br = toBufferedReader(in);
+		Map<String, Ref> refs;
+		try {
+			refs = d.readAdvertisedImpl(br);
+		} finally {
+			br.close();
+		}
+
+		if (!refs.containsKey(Constants.HEAD)) {
+			// If HEAD was not published in the info/refs file (it usually
+			// is not there) download HEAD by itself as a loose file and do
+			// the resolution by hand.
+			//
+			HttpURLConnection conn = httpOpen(new URL(baseUrl, Constants.HEAD));
+			int status = HttpSupport.response(conn);
+			switch (status) {
+			case HttpURLConnection.HTTP_OK: {
+				br = toBufferedReader(openInputStream(conn));
+				try {
+					String line = br.readLine();
+					if (line != null && line.startsWith("ref: ")) {
+						Ref src = refs.get(line.substring(5));
+						if (src != null) {
+							refs.put(Constants.HEAD, new Ref(
+									Ref.Storage.NETWORK, Constants.HEAD, src
+											.getName(), src.getObjectId()));
+						}
+					} else if (line != null && ObjectId.isId(line)) {
+						refs.put(Constants.HEAD, new Ref(Ref.Storage.NETWORK,
+								Constants.HEAD, ObjectId.fromString(line)));
+					}
+				} finally {
+					br.close();
+				}
+				break;
+			}
+
+			case HttpURLConnection.HTTP_NOT_FOUND:
+				break;
+
+			default:
+				throw new TransportException(uri, "cannot read HEAD: " + status
+						+ " " + conn.getResponseMessage());
+			}
+		}
+
+		WalkFetchConnection wfc = new WalkFetchConnection(this, d);
+		wfc.available(refs);
+		return wfc;
+	}
+
+	private BufferedReader toBufferedReader(InputStream in) {
+		return new BufferedReader(new InputStreamReader(in, Constants.CHARSET));
+	}
+
 	@Override
 	public PushConnection openPush() throws NotSupportedException,
 			TransportException {
-- 
GitLab