dumb-http: do not pass NULL path to parse_pack_index
authorJeff King <peff@peff.net>
Tue, 27 Jan 2015 20:02:27 +0000 (15:02 -0500)
committerJunio C Hamano <gitster@pobox.com>
Tue, 27 Jan 2015 20:41:45 +0000 (12:41 -0800)
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>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
http.c
t/t5550-http-fetch-dumb.sh
diff --git a/http.c b/http.c
index 94e1afdee7890825dfda0946b999f524265603fc..0031b3a939a5224cb74970e8f1e5a642678bb0eb 100644 (file)
--- a/http.c
+++ b/http.c
@@ -1157,7 +1157,7 @@ static int fetch_and_setup_pack_index(struct packed_git **packs_head,
        int ret;
 
        if (has_pack_index(sha1)) {
        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;
                if (!new_pack)
                        return -1; /* parse_pack_index() already issued error message */
                goto add_pack;
index 1a3a2b6c1a20558a019143d1abbd2168af0caf53..c3ba7ed0fea8e43c65d46cfdce985839e8729874 100755 (executable)
@@ -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
 test_expect_success 'did not use upload-pack service' '
        grep '/git-upload-pack' <"$HTTPD_ROOT_PATH"/access.log >act
        : >exp