git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] dumb-http: do not pass NULL path to parse_pack_index

From
Jeff King <peff@peff.net>
Date
Jan 27, 2015, 20:02 UTC
Message-ID
<20150127200226.GA19618@peff.net>
In-Reply-To
<20150127181220.GA17067@peff.net>
On Tue, Jan 27, 2015 at 01:12:20PM -0500, Jeff King wrote:
Show 5 quoted lines
> It looks like the culprit is 7b64469 (Allow parse_pack_index on
> temporary files, 2010-04-19). It added a new "idx_path" parameter to
> parse_pack_index, which we pass as NULL.  That causes its call to
> check_packed_git_idx to fail (because it has no idea what file we are
> talking about!).

This is not quite right. That refactoring commit correctly passes the result of sha1_pack_index_name() for the newly-added parameter. It's the _next_ commit which then erroneously passes NULL. :)

Here's my fix with a proper commit message. I tweaked the title on your test, as I didn't find the original very descriptive. I also bumped the call to sha1_pack_index_name() into the caller, as that makes more sense to me after reading the older commits (and there are literally no other callers outside of this function).

-- >8 -- Once upon a time, dumb http always fetched .idx files directly into their final location, and then checked their validity with parse_pack_index. This was refactored in commit 750ef42 (http-fetch: Use temporary files for pack-*.idx until verified, 2010-04-19), which uses the following logic:

  1. If we have the idx already in place, see if it's
     valid (using parse_pack_index). If so, use it.
  2. Otherwise, fetch the .idx to a tempfile, check
     that, and if so move it into place.
  3. Either way, fetch the pack itself if necessary.

However, it got step 1 wrong. We pass a NULL path parameter to parse_pack_index, so an existing .idx file always looks broken. Worse, we do not treat this broken .idx as an opportunity to re-fetch, but instead return an error, ignoring the pack entirely. This can lead to a dumb-http fetch failing to retrieve the necessary objects.

This doesn't come up much in practice, because it must be a packfile that we found out about (and whose .idx we stored) during an earlier dumb-http fetch, but whose packfile we _didn't_ fetch. I.e., we did a partial clone of a repository, didn't need some packfiles, and now a followup fetch needs them.

Discovery and tests by Charles Bailey <charles@hashpling.org>.
Signed-off-by: Jeff King <peff@peff.net>
---
I'm happy to flip the authorship on this. You have more lines in it than
I do. :)

As I mentioned before, I think we could treat a broken .idx file differently (by deleting and refetching), but I doubt it matters in practice. The only reason this came up at all is that our test for "broken" was bogus, and it may be better to let a user diagnose and deal with breakage.

 http.c                     |  2 +-
 t/t5550-http-fetch-dumb.sh | 18 ++++++++++++++++++
 2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/http.c b/http.c
index 040f362..f2373c0 100644
--- a/http.c
+++ b/http.c
@@ -1240,7 +1240,7 @@ static int fetch_and_setup_pack_index(struct packed_git **packs_head,
 	int ret;
 
 	if (has_pack_index(sha1)) {
-		new_pack = parse_pack_index(sha1, NULL);
+		new_pack = parse_pack_index(sha1, sha1_pack_index_name(sha1));
 		if (!new_pack)
 			return -1; /* parse_pack_index() already issued error message */
 		goto add_pack;
diff --git a/t/t5550-http-fetch-dumb.sh b/t/t5550-http-fetch-dumb.sh
index ac71418..6da9422 100755
--- a/t/t5550-http-fetch-dumb.sh
+++ b/t/t5550-http-fetch-dumb.sh
@@ -165,6 +165,24 @@ test_expect_success 'fetch notices corrupt idx' '
 	)
 '
 
+test_expect_success 'fetch can handle previously-fetched .idx files' '
+	git checkout --orphan branch1 &&
+	echo base >file &&
+	git add file &&
+	git commit -m base &&
+	git --bare init "$HTTPD_DOCUMENT_ROOT_PATH"/repo_packed_branches.git &&
+	git push "$HTTPD_DOCUMENT_ROOT_PATH"/repo_packed_branches.git branch1 &&
+	git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH"/repo_packed_branches.git repack -d &&
+	git checkout -b branch2 branch1 &&
+	echo b2 >>file &&
+	git commit -a -m b2 &&
+	git push "$HTTPD_DOCUMENT_ROOT_PATH"/repo_packed_branches.git branch2 &&
+	git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH"/repo_packed_branches.git repack -d &&
+	git --bare init clone_packed_branches.git &&
+	git --git-dir=clone_packed_branches.git fetch "$HTTPD_URL"/dumb/repo_packed_branches.git branch1:branch1 &&
+	git --git-dir=clone_packed_branches.git fetch "$HTTPD_URL"/dumb/repo_packed_branches.git branch2:branch2
+'
+
 test_expect_success 'did not use upload-pack service' '
 	grep '/git-upload-pack' <"$HTTPD_ROOT_PATH"/access.log >act
 	: >exp
-- 
2.3.0.rc1.287.g761fd19
Previous: Charles BaileyNext: Charles Bailey
Message 4 of 6 in “Add failing test for fetching from multiple packs over dumb httpd”
  1. Add failing test for fetching from multiple packs over dumb httpdCharles Bailey, Jan 27, 2015
  2. Jeff KingJan 27, 2015
  3. Charles BaileyJan 27, 2015
  4. dumb-http: do not pass NULL path to parse_pack_indexJeff King, Jan 27, 2015
  5. Charles BaileyJan 27, 2015
  6. Junio C HamanoJan 27, 2015

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.