]>
Commit | Line | Data |
---|---|---|
c2e86add | 1 | #include "builtin.h" |
8e440259 | 2 | #include "tag.h" |
47f351e9 | 3 | #include "replace-object.h" |
cbd53a21 | 4 | #include "object-store.h" |
acf9de4c | 5 | #include "fsck.h" |
acfc0133 ÆAB |
6 | #include "config.h" |
7 | ||
8 | static struct fsck_options fsck_options = FSCK_OPTIONS_STRICT; | |
9 | ||
10 | static int mktag_config(const char *var, const char *value, void *cb) | |
11 | { | |
12 | return fsck_config_internal(var, value, cb, &fsck_options); | |
13 | } | |
ec4465ad | 14 | |
acf9de4c ÆAB |
15 | static int mktag_fsck_error_func(struct fsck_options *o, |
16 | const struct object_id *oid, | |
17 | enum object_type object_type, | |
18 | int msg_type, const char *message) | |
ec4465ad | 19 | { |
acf9de4c ÆAB |
20 | switch (msg_type) { |
21 | case FSCK_WARN: | |
22 | case FSCK_ERROR: | |
23 | /* | |
24 | * We treat both warnings and errors as errors, things | |
25 | * like missing "tagger" lines are "only" warnings | |
26 | * under fsck, we've always considered them an error. | |
27 | */ | |
28 | fprintf_ln(stderr, "error: tag input does not pass fsck: %s", message); | |
29 | return 1; | |
30 | default: | |
31 | BUG("%d (FSCK_IGNORE?) should never trigger this callback", | |
32 | msg_type); | |
ec4465ad | 33 | } |
ec4465ad LT |
34 | } |
35 | ||
acf9de4c | 36 | static int verify_object_in_tag(struct object_id *tagged_oid, int *tagged_type) |
ec4465ad | 37 | { |
acf9de4c ÆAB |
38 | int ret; |
39 | enum object_type type; | |
40 | unsigned long size; | |
41 | void *buffer; | |
42 | const struct object_id *repl; | |
43 | ||
44 | buffer = read_object_file(tagged_oid, &type, &size); | |
45 | if (!buffer) | |
46 | die("could not read tagged object '%s'", | |
47 | oid_to_hex(tagged_oid)); | |
48 | if (type != *tagged_type) | |
49 | die("object '%s' tagged as '%s', but is a '%s' type", | |
50 | oid_to_hex(tagged_oid), | |
51 | type_name(*tagged_type), type_name(type)); | |
52 | ||
53 | repl = lookup_replace_object(the_repository, tagged_oid); | |
54 | ret = check_object_signature(the_repository, repl, | |
55 | buffer, size, type_name(*tagged_type)); | |
56 | free(buffer); | |
c818566d | 57 | |
acf9de4c | 58 | return ret; |
ec4465ad LT |
59 | } |
60 | ||
112dd514 | 61 | int cmd_mktag(int argc, const char **argv, const char *prefix) |
ec4465ad | 62 | { |
f285a2d7 | 63 | struct strbuf buf = STRBUF_INIT; |
acf9de4c ÆAB |
64 | struct object_id tagged_oid; |
65 | int tagged_type; | |
a09c985e | 66 | struct object_id result; |
ec4465ad LT |
67 | |
68 | if (argc != 1) | |
33e8fc87 | 69 | usage("git mktag"); |
ec4465ad | 70 | |
dfe39487 | 71 | if (strbuf_read(&buf, 0, 0) < 0) |
0721c314 | 72 | die_errno("could not read from stdin"); |
ec4465ad | 73 | |
acf9de4c ÆAB |
74 | fsck_options.error_func = mktag_fsck_error_func; |
75 | fsck_set_msg_type(&fsck_options, "extraheaderentry", "warn"); | |
acfc0133 ÆAB |
76 | /* config might set fsck.extraHeaderEntry=* again */ |
77 | git_config(mktag_config, NULL); | |
acf9de4c ÆAB |
78 | if (fsck_tag_standalone(NULL, buf.buf, buf.len, &fsck_options, |
79 | &tagged_oid, &tagged_type)) | |
80 | die("tag on stdin did not pass our strict fsck check"); | |
81 | ||
82 | if (verify_object_in_tag(&tagged_oid, &tagged_type)) | |
83 | die("tag on stdin did not refer to a valid object"); | |
ec4465ad | 84 | |
a09c985e | 85 | if (write_object_file(buf.buf, buf.len, tag_type, &result) < 0) |
ec4465ad | 86 | die("unable to write tag file"); |
e7332f96 | 87 | |
fd17f5b5 | 88 | strbuf_release(&buf); |
40ef015a | 89 | puts(oid_to_hex(&result)); |
ec4465ad LT |
90 | return 0; |
91 | } |