revision: --max-age alone does not need limit_list() anymore.
[git.git] / http-fetch.c
index 72edf28..dc67218 100644 (file)
@@ -8,6 +8,7 @@
 #define RANGE_HEADER_SIZE 30
 
 static int got_alternates = -1;
+static int corrupt_object_found = 0;
 
 static struct curl_slist *no_pragma_header;
 
@@ -130,7 +131,7 @@ static void start_object_request(struct object_request *obj_req)
 
        if (obj_req->local < 0) {
                obj_req->state = ABORTED;
-               error("Couldn't create temporary file %s for %s: %s\n",
+               error("Couldn't create temporary file %s for %s: %s",
                      obj_req->tmpfile, obj_req->filename, strerror(errno));
                return;
        }
@@ -311,7 +312,7 @@ void fill_active_slots(void)
        while (active_requests < max_requests && obj_req != NULL) {
                if (obj_req->state == WAITING) {
                        if (has_sha1_file(obj_req->sha1))
-                               release_object_request(obj_req);
+                               obj_req->state = COMPLETE;
                        else
                                start_object_request(obj_req);
                        curl_multi_perform(curlm, &num_transfers);
@@ -468,13 +469,15 @@ static void process_alternates_response(void *callback_data)
                                         alt_req->url);
                        active_requests++;
                        slot->in_use = 1;
-                       if (start_active_slot(slot)) {
-                               return;
-                       } else {
+                       if (slot->finished != NULL)
+                               (*slot->finished) = 0;
+                       if (!start_active_slot(slot)) {
                                got_alternates = -1;
                                slot->in_use = 0;
-                               return;
+                               if (slot->finished != NULL)
+                                       (*slot->finished) = 1;
                        }
+                       return;
                }
        } else if (slot->curl_result != CURLE_OK) {
                if (slot->http_code != 404 &&
@@ -775,6 +778,20 @@ static int fetch_pack(struct alt_base *repo, unsigned char *sha1)
        return 0;
 }
 
+static void abort_object_request(struct object_request *obj_req)
+{
+       if (obj_req->local >= 0) {
+               close(obj_req->local);
+               obj_req->local = -1;
+       }
+       unlink(obj_req->tmpfile);
+       if (obj_req->slot) {
+               release_active_slot(obj_req->slot);
+               obj_req->slot = NULL;
+       }
+       release_object_request(obj_req);
+}
+
 static int fetch_object(struct alt_base *repo, unsigned char *sha1)
 {
        char *hex = sha1_to_hex(sha1);
@@ -787,7 +804,7 @@ static int fetch_object(struct alt_base *repo, unsigned char *sha1)
                return error("Couldn't find request for %s in the queue", hex);
 
        if (has_sha1_file(obj_req->sha1)) {
-               release_object_request(obj_req);
+               abort_object_request(obj_req);
                return 0;
        }
 
@@ -818,13 +835,13 @@ static int fetch_object(struct alt_base *repo, unsigned char *sha1)
                                    obj_req->errorstr, obj_req->curl_result,
                                    obj_req->http_code, hex);
        } else if (obj_req->zret != Z_STREAM_END) {
-               ret = error("File %s (%s) corrupt\n", hex, obj_req->url);
+               corrupt_object_found++;
+               ret = error("File %s (%s) corrupt", hex, obj_req->url);
        } else if (memcmp(obj_req->sha1, obj_req->real_sha1, 20)) {
-               ret = error("File %s has bad hash\n", hex);
+               ret = error("File %s has bad hash", hex);
        } else if (obj_req->rename < 0) {
-               ret = error("unable to write sha1 filename %s: %s",
-                           obj_req->filename,
-                           strerror(obj_req->rename));
+               ret = error("unable to write sha1 filename %s",
+                           obj_req->filename);
        }
 
        release_object_request(obj_req);
@@ -843,7 +860,7 @@ int fetch(unsigned char *sha1)
                fetch_alternates(alt->base);
                altbase = altbase->next;
        }
-       return error("Unable to find %s under %s\n", sha1_to_hex(sha1),
+       return error("Unable to find %s under %s", sha1_to_hex(sha1),
                     alt->base);
 }
 
@@ -978,5 +995,11 @@ int main(int argc, char **argv)
 
        http_cleanup();
 
+       if (corrupt_object_found) {
+               fprintf(stderr,
+"Some loose object were found to be corrupt, but they might be just\n"
+"a false '404 Not Found' error message sent with incorrect HTTP\n"
+"status code.  Suggest running git fsck-objects.\n");
+       }
        return rc;
 }