fsck: parse loose object paths directly
[gitweb.git] / builtin / fsck.c
index 2de272ea3659411b58d38d703a48790d55d6a12b..4b91ee95e66396285d2eb8e67ab597e84d76fab7 100644 (file)
@@ -268,7 +268,7 @@ static void check_unreachable_object(struct object *obj)
                        if (!(f = fopen(filename, "w")))
                                die_errno("Could not open '%s'", filename);
                        if (obj->type == OBJ_BLOB) {
-                               if (stream_blob_to_fd(fileno(f), obj->oid.hash, NULL, 1))
+                               if (stream_blob_to_fd(fileno(f), &obj->oid, NULL, 1))
                                        die_errno("Could not write '%s'", filename);
                        } else
                                fprintf(f, "%s\n", describe_object(obj));
@@ -362,18 +362,6 @@ static int fsck_obj(struct object *obj)
        return 0;
 }
 
-static int fsck_sha1(const unsigned char *sha1)
-{
-       struct object *obj = parse_object(sha1);
-       if (!obj) {
-               errors_found |= ERROR_OBJECT;
-               return error("%s: object corrupt or missing",
-                            sha1_to_hex(sha1));
-       }
-       obj->flags |= HAS_OBJ;
-       return fsck_obj(obj);
-}
-
 static int fsck_obj_buffer(const unsigned char *sha1, enum object_type type,
                           unsigned long size, void *buffer, int *eaten)
 {
@@ -488,9 +476,41 @@ static void get_default_heads(void)
        }
 }
 
+static struct object *parse_loose_object(const unsigned char *sha1,
+                                        const char *path)
+{
+       struct object *obj;
+       void *contents;
+       enum object_type type;
+       unsigned long size;
+       int eaten;
+
+       if (read_loose_object(path, sha1, &type, &size, &contents) < 0)
+               return NULL;
+
+       if (!contents && type != OBJ_BLOB)
+               die("BUG: read_loose_object streamed a non-blob");
+
+       obj = parse_object_buffer(sha1, type, size, contents, &eaten);
+
+       if (!eaten)
+               free(contents);
+       return obj;
+}
+
 static int fsck_loose(const unsigned char *sha1, const char *path, void *data)
 {
-       if (fsck_sha1(sha1))
+       struct object *obj = parse_loose_object(sha1, path);
+
+       if (!obj) {
+               errors_found |= ERROR_OBJECT;
+               error("%s: object corrupt or missing: %s",
+                     sha1_to_hex(sha1), path);
+               return 0; /* keep checking other objects */
+       }
+
+       obj->flags = HAS_OBJ;
+       if (fsck_obj(obj))
                errors_found |= ERROR_OBJECT;
        return 0;
 }
@@ -644,14 +664,8 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
                fsck_object_dir(get_object_directory());
 
                prepare_alt_odb();
-               for (alt = alt_odb_list; alt; alt = alt->next) {
-                       /* directory name, minus trailing slash */
-                       size_t namelen = alt->name - alt->base - 1;
-                       struct strbuf name = STRBUF_INIT;
-                       strbuf_add(&name, alt->base, namelen);
-                       fsck_object_dir(name.buf);
-                       strbuf_release(&name);
-               }
+               for (alt = alt_odb_list; alt; alt = alt->next)
+                       fsck_object_dir(alt->path);
        }
 
        if (check_full) {
@@ -722,7 +736,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
                        mode = active_cache[i]->ce_mode;
                        if (S_ISGITLINK(mode))
                                continue;
-                       blob = lookup_blob(active_cache[i]->sha1);
+                       blob = lookup_blob(active_cache[i]->oid.hash);
                        if (!blob)
                                continue;
                        obj = &blob->object;