sha1-file: fix outdated sha1 comment references
[gitweb.git] / sha1-file.c
index 503262edd2a6ad3e03eda39640c09fde33afb4ab..c781ae847f042b65aa90bb59e916bbc8adc23f92 100644 (file)
@@ -124,7 +124,7 @@ const char *empty_blob_oid_hex(void)
 
 /*
  * This is meant to hold a *small* number of objects that you would
- * want read_sha1_file() to be able to return, but yet you do not want
+ * want read_object_file() to be able to return, but yet you do not want
  * to write them into the object store (e.g. a browse-only
  * application).
  */
@@ -798,8 +798,8 @@ void *xmmap(void *start, size_t length,
 
 /*
  * With an in-core object data in "map", rehash it to make sure the
- * object name actually matches "sha1" to detect object corruption.
- * With "map" == NULL, try reading the object named with "sha1" using
+ * object name actually matches "oid" to detect object corruption.
+ * With "map" == NULL, try reading the object named with "oid" using
  * the streaming interface and rehash it to do the same.
  */
 int check_object_signature(const struct object_id *oid, void *map,
@@ -822,7 +822,7 @@ int check_object_signature(const struct object_id *oid, void *map,
                return -1;
 
        /* Generate the header */
-       hdrlen = xsnprintf(hdr, sizeof(hdr), "%s %lu", type_name(obj_type), size) + 1;
+       hdrlen = xsnprintf(hdr, sizeof(hdr), "%s %"PRIuMAX , type_name(obj_type), (uintmax_t)size) + 1;
 
        /* Sha1.. */
        the_hash_algo->init_fn(&c);
@@ -921,6 +921,22 @@ static int open_sha1_file(struct repository *r,
        return -1;
 }
 
+static int quick_has_loose(struct repository *r,
+                          const unsigned char *sha1)
+{
+       struct object_id oid;
+       struct object_directory *odb;
+
+       hashcpy(oid.hash, sha1);
+
+       prepare_alt_odb(r);
+       for (odb = r->objects->odb; odb; odb = odb->next) {
+               if (oid_array_lookup(odb_loose_cache(odb, &oid), &oid) >= 0)
+                       return 1;
+       }
+       return 0;
+}
+
 /*
  * Map the loose object at "path" if it is not NULL, or the path found by
  * searching for a loose object named "sha1".
@@ -1171,6 +1187,8 @@ static int sha1_loose_object_info(struct repository *r,
        if (!oi->typep && !oi->type_name && !oi->sizep && !oi->contentp) {
                const char *path;
                struct stat st;
+               if (!oi->disk_sizep && (flags & OBJECT_INFO_QUICK))
+                       return quick_has_loose(r, sha1) ? 0 : -1;
                if (stat_sha1_file(r, sha1, &st, &path) < 0)
                        return -1;
                if (oi->disk_sizep)
@@ -1465,7 +1483,7 @@ static void write_object_file_prepare(const void *buf, unsigned long len,
        git_hash_ctx c;
 
        /* Generate the header */
-       *hdrlen = xsnprintf(hdr, *hdrlen, "%s %lu", type, len)+1;
+       *hdrlen = xsnprintf(hdr, *hdrlen, "%s %"PRIuMAX , type, (uintmax_t)len)+1;
 
        /* Sha1.. */
        the_hash_algo->init_fn(&c);
@@ -1730,7 +1748,7 @@ int force_object_loose(const struct object_id *oid, time_t mtime)
        buf = read_object(oid->hash, &type, &len);
        if (!buf)
                return error(_("cannot read sha1_file for %s"), oid_to_hex(oid));
-       hdrlen = xsnprintf(hdr, sizeof(hdr), "%s %lu", type_name(type), len) + 1;
+       hdrlen = xsnprintf(hdr, sizeof(hdr), "%s %"PRIuMAX , type_name(type), (uintmax_t)len) + 1;
        ret = write_loose_object(oid, hdr, hdrlen, buf, len, mtime);
        free(buf);
 
@@ -2125,6 +2143,46 @@ int for_each_loose_object(each_loose_object_fn cb, void *data,
        return 0;
 }
 
+static int append_loose_object(const struct object_id *oid, const char *path,
+                              void *data)
+{
+       oid_array_append(data, oid);
+       return 0;
+}
+
+struct oid_array *odb_loose_cache(struct object_directory *odb,
+                                 const struct object_id *oid)
+{
+       int subdir_nr = oid->hash[0];
+       struct strbuf buf = STRBUF_INIT;
+
+       if (subdir_nr < 0 ||
+           subdir_nr >= ARRAY_SIZE(odb->loose_objects_subdir_seen))
+               BUG("subdir_nr out of range");
+
+       if (odb->loose_objects_subdir_seen[subdir_nr])
+               return &odb->loose_objects_cache[subdir_nr];
+
+       strbuf_addstr(&buf, odb->path);
+       for_each_file_in_obj_subdir(subdir_nr, &buf,
+                                   append_loose_object,
+                                   NULL, NULL,
+                                   &odb->loose_objects_cache[subdir_nr]);
+       odb->loose_objects_subdir_seen[subdir_nr] = 1;
+       strbuf_release(&buf);
+       return &odb->loose_objects_cache[subdir_nr];
+}
+
+void odb_clear_loose_cache(struct object_directory *odb)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(odb->loose_objects_cache); i++)
+               oid_array_clear(&odb->loose_objects_cache[i]);
+       memset(&odb->loose_objects_subdir_seen, 0,
+              sizeof(odb->loose_objects_subdir_seen));
+}
+
 static int check_stream_sha1(git_zstream *stream,
                             const char *hdr,
                             unsigned long size,
@@ -2151,7 +2209,8 @@ static int check_stream_sha1(git_zstream *stream,
         * see the comment in unpack_sha1_rest for details.
         */
        while (total_read <= size &&
-              (status == Z_OK || status == Z_BUF_ERROR)) {
+              (status == Z_OK ||
+               (status == Z_BUF_ERROR && !stream->avail_out))) {
                stream->next_out = buf;
                stream->avail_out = sizeof(buf);
                if (size - total_read < stream->avail_out)