dumb-http: do not pass NULL path to parse_pack_index

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>

Jeff King committed Jan 27, 2015 at 15:02 UTC 8b9c2dd4dee01b5a0a9c5cfdd5a107f78edaceb7
2 files changed +19 -1
http.c
+1 -1
@@ -1157,7 +1157,7 @@ static int fetch_and_setup_pack_index(struct packed_git **packs_head,
1157 int ret;
1158
1159 if (has_pack_index(sha1)) {
1160 - new_pack = parse_pack_index(sha1, NULL);
1160 + new_pack = parse_pack_index(sha1, sha1_pack_index_name(sha1));
1161 if (!new_pack)
1162 return -1; /* parse_pack_index() already issued error message */
1163 goto add_pack;
t/t5550-http-fetch-dumb.sh
+18
@@ -165,6 +165,24 @@ test_expect_success 'fetch notices corrupt idx' '
165 )
166 '
167
168 +test_expect_success 'fetch can handle previously-fetched .idx files' '
169 + git checkout --orphan branch1 &&
170 + echo base >file &&
171 + git add file &&
172 + git commit -m base &&
173 + git --bare init "$HTTPD_DOCUMENT_ROOT_PATH"/repo_packed_branches.git &&
174 + git push "$HTTPD_DOCUMENT_ROOT_PATH"/repo_packed_branches.git branch1 &&
175 + git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH"/repo_packed_branches.git repack -d &&
176 + git checkout -b branch2 branch1 &&
177 + echo b2 >>file &&
178 + git commit -a -m b2 &&
179 + git push "$HTTPD_DOCUMENT_ROOT_PATH"/repo_packed_branches.git branch2 &&
180 + git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH"/repo_packed_branches.git repack -d &&
181 + git --bare init clone_packed_branches.git &&
182 + git --git-dir=clone_packed_branches.git fetch "$HTTPD_URL"/dumb/repo_packed_branches.git branch1:branch1 &&
183 + git --git-dir=clone_packed_branches.git fetch "$HTTPD_URL"/dumb/repo_packed_branches.git branch2:branch2
184 +'
185 +
186 test_expect_success 'did not use upload-pack service' '
187 grep '/git-upload-pack' <"$HTTPD_ROOT_PATH"/access.log >act
188 : >exp