Add missing includes and forward declarations
[gitweb.git] / builtin / index-pack.c
index b28ebfadd433727a4d8344ecd56e458f3abc03a7..de311febe3034cb17cb26a57757c144842af8d9f 100644 (file)
@@ -9,10 +9,11 @@
 #include "tree.h"
 #include "progress.h"
 #include "fsck.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
 #include "streaming.h"
 #include "thread-utils.h"
 #include "packfile.h"
+#include "object-store.h"
 
 static const char index_pack_usage[] =
 "git index-pack [-v] [-o <index-file>] [--keep | --keep=<msg>] [--verify] [--strict] (<pack-file> | --stdin [--fix-thin] [<pack-file>])";
@@ -49,6 +50,7 @@ struct thread_local {
        int pack_fd;
 };
 
+/* Remember to update object flag allocation in object.h */
 #define FLAG_LINK (1u<<20)
 #define FLAG_CHECKED (1u<<21)
 
@@ -221,7 +223,7 @@ static unsigned check_object(struct object *obj)
 
        if (!(obj->flags & FLAG_CHECKED)) {
                unsigned long size;
-               int type = sha1_object_info(obj->oid.hash, &size);
+               int type = oid_object_info(the_repository, &obj->oid, &size);
                if (type <= 0)
                        die(_("did not receive expected object %s"),
                              oid_to_hex(&obj->oid));
@@ -771,7 +773,7 @@ static int check_collison(struct object_entry *entry)
 
        memset(&data, 0, sizeof(data));
        data.entry = entry;
-       data.st = open_istream(entry->idx.oid.hash, &type, &size, NULL);
+       data.st = open_istream(&entry->idx.oid, &type, &size, NULL);
        if (!data.st)
                return -1;
        if (size != entry->size || type != entry->type)
@@ -810,12 +812,12 @@ static void sha1_object(const void *data, struct object_entry *obj_entry,
                enum object_type has_type;
                unsigned long has_size;
                read_lock();
-               has_type = sha1_object_info(oid->hash, &has_size);
+               has_type = oid_object_info(the_repository, oid, &has_size);
                if (has_type < 0)
                        die(_("cannot read existing object info %s"), oid_to_hex(oid));
                if (has_type != type || has_size != size)
                        die(_("SHA1 COLLISION FOUND WITH %s !"), oid_to_hex(oid));
-               has_data = read_sha1_file(oid->hash, &has_type, &has_size);
+               has_data = read_object_file(oid, &has_type, &has_size);
                read_unlock();
                if (!data)
                        data = new_data = get_data_from_pack(obj_entry);
@@ -827,14 +829,17 @@ static void sha1_object(const void *data, struct object_entry *obj_entry,
                free(has_data);
        }
 
-       if (strict) {
+       if (strict || do_fsck_object) {
                read_lock();
                if (type == OBJ_BLOB) {
-                       struct blob *blob = lookup_blob(oid);
+                       struct blob *blob = lookup_blob(the_repository, oid);
                        if (blob)
                                blob->object.flags |= FLAG_CHECKED;
                        else
                                die(_("invalid blob object %s"), oid_to_hex(oid));
+                       if (do_fsck_object &&
+                           fsck_object(&blob->object, (void *)data, size, &fsck_options))
+                               die(_("fsck error in packed object"));
                } else {
                        struct object *obj;
                        int eaten;
@@ -846,14 +851,15 @@ static void sha1_object(const void *data, struct object_entry *obj_entry,
                         * we do not need to free the memory here, as the
                         * buf is deleted by the caller.
                         */
-                       obj = parse_object_buffer(oid, type, size, buf,
+                       obj = parse_object_buffer(the_repository, oid, type,
+                                                 size, buf,
                                                  &eaten);
                        if (!obj)
                                die(_("invalid %s"), type_name(type));
                        if (do_fsck_object &&
                            fsck_object(obj, buf, size, &fsck_options))
-                               die(_("Error in object"));
-                       if (fsck_walk(obj, NULL, &fsck_options))
+                               die(_("fsck error in packed object"));
+                       if (strict && fsck_walk(obj, NULL, &fsck_options))
                                die(_("Not all child objects of %s are reachable"), oid_to_hex(&obj->oid));
 
                        if (obj->type == OBJ_TREE) {
@@ -864,7 +870,7 @@ static void sha1_object(const void *data, struct object_entry *obj_entry,
                        if (obj->type == OBJ_COMMIT) {
                                struct commit *commit = (struct commit *) obj;
                                if (detach_commit_buffer(commit, NULL) != data)
-                                       die("BUG: parse_object_buffer transmogrified our buffer");
+                                       BUG("parse_object_buffer transmogrified our buffer");
                        }
                        obj->flags |= FLAG_CHECKED;
                }
@@ -1013,7 +1019,7 @@ static struct base_data *find_unresolved_deltas_1(struct base_data *base,
 
                if (!compare_and_swap_type(&child->real_type, OBJ_REF_DELTA,
                                           base->obj->real_type))
-                       die("BUG: child->real_type != OBJ_REF_DELTA");
+                       BUG("child->real_type != OBJ_REF_DELTA");
 
                resolve_delta(child, base, result);
                if (base->ref_first == base->ref_last && base->ofs_last == -1)
@@ -1269,7 +1275,7 @@ static void conclude_pack(int fix_thin_pack, const char *curr_pack, unsigned cha
                            nr_objects - nr_objects_initial);
                stop_progress_msg(&progress, msg.buf);
                strbuf_release(&msg);
-               hashclose(f, tail_hash, 0);
+               finalize_hashfile(f, tail_hash, 0);
                hashcpy(read_hash, pack_hash);
                fixup_pack_header_footer(output_fd, pack_hash,
                                         curr_pack, nr_objects,
@@ -1373,7 +1379,8 @@ static void fix_unresolved_deltas(struct hashfile *f)
 
                if (objects[d->obj_no].real_type != OBJ_REF_DELTA)
                        continue;
-               base_obj->data = read_sha1_file(d->oid.hash, &type, &base_obj->size);
+               base_obj->data = read_object_file(&d->oid, &type,
+                                                 &base_obj->size);
                if (!base_obj->data)
                        continue;
 
@@ -1476,6 +1483,13 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
        } else
                chmod(final_index_name, 0444);
 
+       if (do_fsck_object) {
+               struct packed_git *p;
+               p = add_packed_git(final_index_name, strlen(final_index_name), 0);
+               if (p)
+                       install_packed_git(the_repository, p);
+       }
+
        if (!from_stdin) {
                printf("%s\n", sha1_to_hex(hash));
        } else {
@@ -1540,12 +1554,13 @@ static void read_v2_anomalous_offsets(struct packed_git *p,
 {
        const uint32_t *idx1, *idx2;
        uint32_t i;
+       const uint32_t hashwords = the_hash_algo->rawsz / sizeof(uint32_t);
 
        /* The address of the 4-byte offset table */
        idx1 = (((const uint32_t *)p->index_data)
                + 2 /* 8-byte header */
                + 256 /* fan out */
-               + 5 * p->num_objects /* 20-byte SHA-1 table */
+               + hashwords * p->num_objects /* object ID table */
                + p->num_objects /* CRC32 table */
                );
 
@@ -1590,7 +1605,7 @@ static void read_idx_option(struct pack_idx_option *opts, const char *pack_name)
        /*
         * Get rid of the idx file as we do not need it anymore.
         * NEEDSWORK: extract this bit from free_pack_by_name() in
-        * sha1_file.c, perhaps?  It shouldn't matter very much as we
+        * sha1-file.c, perhaps?  It shouldn't matter very much as we
         * know we haven't installed this pack (hence we never have
         * read anything from it).
         */
@@ -1688,6 +1703,8 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
                        } else if (!strcmp(arg, "--check-self-contained-and-connected")) {
                                strict = 1;
                                check_self_contained_and_connected = 1;
+                       } else if (!strcmp(arg, "--fsck-objects")) {
+                               do_fsck_object = 1;
                        } else if (!strcmp(arg, "--verify")) {
                                verify = 1;
                        } else if (!strcmp(arg, "--verify-stat")) {
@@ -1815,6 +1832,10 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
                      pack_hash);
        else
                close(input_fd);
+
+       if (do_fsck_object && fsck_finish(&fsck_options))
+               die(_("fsck error in pack objects"));
+
        free(objects);
        strbuf_release(&index_name_buf);
        if (pack_name == NULL)