@matheusbsbs / matheus-bagliano / commits / 0153be05ae
Fork 0

index-pack: introduce checking mode

Adds strict option, which bails out if the pack would introduces broken object or links in the repository. Signed-off-by: Martin Koegler <mkoegler@auto.tuwien.ac.at> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Martin Koegler committed Feb 25, 2008 at 22:46 UTC 0153be05ae332b8df9bb21d8d249881323e30725
2 files changed +90 -1
Documentation/git-index-pack.txt
+3
@@ -75,6 +75,9 @@ OPTIONS
75 to force the version for the generated pack index, and to force
76 64-bit index entries on objects located above the given offset.
77
78 +--strict::
79 + Die, if the pack contains broken objects or links.
80 +
81
82 Note
83 ----
index-pack.c
+87 -1
@@ -7,9 +7,10 @@
7 #include "tag.h"
8 #include "tree.h"
9 #include "progress.h"
10 +#include "fsck.h"
11
12 static const char index_pack_usage[] =
12 -"git-index-pack [-v] [-o <index-file>] [{ ---keep | --keep=<msg> }] { <pack-file> | --stdin [--fix-thin] [<pack-file>] }";
13 +"git-index-pack [-v] [-o <index-file>] [{ ---keep | --keep=<msg> }] [--strict] { <pack-file> | --stdin [--fix-thin] [<pack-file>] }";
14
15 struct object_entry
16 {
@@ -31,6 +32,9 @@ union delta_base {
32 */
33 #define UNION_BASE_SZ 20
34
35 +#define FLAG_LINK (1u<<20)
36 +#define FLAG_CHECKED (1u<<21)
37 +
38 struct delta_entry
39 {
40 union delta_base base;
@@ -44,6 +48,7 @@ static int nr_deltas;
48 static int nr_resolved_deltas;
49
50 static int from_stdin;
51 +static int strict;
52 static int verbose;
53
54 static struct progress *progress;
@@ -56,6 +61,48 @@ static SHA_CTX input_ctx;
61 static uint32_t input_crc32;
62 static int input_fd, output_fd, pack_fd;
63
64 +static int mark_link(struct object *obj, int type, void *data)
65 +{
66 + if (!obj)
67 + return -1;
68 +
69 + if (type != OBJ_ANY && obj->type != type)
70 + die("object type mismatch at %s", sha1_to_hex(obj->sha1));
71 +
72 + obj->flags |= FLAG_LINK;
73 + return 0;
74 +}
75 +
76 +/* The content of each linked object must have been checked
77 + or it must be already present in the object database */
78 +static void check_object(struct object *obj)
79 +{
80 + if (!obj)
81 + return;
82 +
83 + if (!(obj->flags & FLAG_LINK))
84 + return;
85 +
86 + if (!(obj->flags & FLAG_CHECKED)) {
87 + unsigned long size;
88 + int type = sha1_object_info(obj->sha1, &size);
89 + if (type != obj->type || type <= 0)
90 + die("object of unexpected type");
91 + obj->flags |= FLAG_CHECKED;
92 + return;
93 + }
94 +}
95 +
96 +static void check_objects(void)
97 +{
98 + unsigned i, max;
99 +
100 + max = get_max_object_index();
101 + for (i = 0; i < max; i++)
102 + check_object(get_indexed_object(i));
103 +}
104 +
105 +
106 /* Discard current buffer used content. */
107 static void flush(void)
108 {
@@ -341,6 +388,41 @@ static void sha1_object(const void *data, unsigned long size,
388 die("SHA1 COLLISION FOUND WITH %s !", sha1_to_hex(sha1));
389 free(has_data);
390 }
391 + if (strict) {
392 + if (type == OBJ_BLOB) {
393 + struct blob *blob = lookup_blob(sha1);
394 + if (blob)
395 + blob->object.flags |= FLAG_CHECKED;
396 + else
397 + die("invalid blob object %s", sha1_to_hex(sha1));
398 + } else {
399 + struct object *obj;
400 + int eaten;
401 + void *buf = (void *) data;
402 +
403 + /*
404 + * we do not need to free the memory here, as the
405 + * buf is deleted by the caller.
406 + */
407 + obj = parse_object_buffer(sha1, type, size, buf, &eaten);
408 + if (!obj)
409 + die("invalid %s", typename(type));
410 + if (fsck_object(obj, 1, fsck_error_function))
411 + die("Error in object");
412 + if (fsck_walk(obj, mark_link, 0))
413 + die("Not all child objects of %s are reachable", sha1_to_hex(obj->sha1));
414 +
415 + if (obj->type == OBJ_TREE) {
416 + struct tree *item = (struct tree *) obj;
417 + item->buffer = NULL;
418 + }
419 + if (obj->type == OBJ_COMMIT) {
420 + struct commit *commit = (struct commit *) obj;
421 + commit->buffer = NULL;
422 + }
423 + obj->flags |= FLAG_CHECKED;
424 + }
425 + }
426 }
427
428 static void resolve_delta(struct object_entry *delta_obj, void *base_data,
@@ -714,6 +796,8 @@ int main(int argc, char **argv)
796 from_stdin = 1;
797 } else if (!strcmp(arg, "--fix-thin")) {
798 fix_thin_pack = 1;
799 + } else if (!strcmp(arg, "--strict")) {
800 + strict = 1;
801 } else if (!strcmp(arg, "--keep")) {
802 keep_msg = "";
803 } else if (!prefixcmp(arg, "--keep=")) {
@@ -812,6 +896,8 @@ int main(int argc, char **argv)
896 nr_deltas - nr_resolved_deltas);
897 }
898 free(deltas);
899 + if (strict)
900 + check_objects();
901
902 idx_objects = xmalloc((nr_objects) * sizeof(struct pack_idx_entry *));
903 for (i = 0; i < nr_objects; i++)