]>
Commit | Line | Data |
---|---|---|
c2e86add | 1 | #include "builtin.h" |
f394e093 | 2 | #include "gettext.h" |
41771fa4 | 3 | #include "hex.h" |
3f390a36 | 4 | #include "parse-options.h" |
a034e910 | 5 | #include "strbuf.h" |
8e440259 | 6 | #include "tag.h" |
47f351e9 | 7 | #include "replace-object.h" |
87bed179 | 8 | #include "object-file.h" |
a034e910 | 9 | #include "object-store-ll.h" |
acf9de4c | 10 | #include "fsck.h" |
acfc0133 ÆAB |
11 | #include "config.h" |
12 | ||
3f390a36 | 13 | static char const * const builtin_mktag_usage[] = { |
959d670d | 14 | "git mktag", |
3f390a36 ÆAB |
15 | NULL |
16 | }; | |
06ce7915 | 17 | static int option_strict = 1; |
3f390a36 | 18 | |
acfc0133 ÆAB |
19 | static struct fsck_options fsck_options = FSCK_OPTIONS_STRICT; |
20 | ||
0b4e9013 JK |
21 | static int mktag_fsck_error_func(struct fsck_options *o UNUSED, |
22 | const struct object_id *oid UNUSED, | |
23 | enum object_type object_type UNUSED, | |
1b32b59f | 24 | enum fsck_msg_type msg_type, |
0b4e9013 | 25 | enum fsck_msg_id msg_id UNUSED, |
1b32b59f | 26 | const char *message) |
ec4465ad | 27 | { |
acf9de4c ÆAB |
28 | switch (msg_type) { |
29 | case FSCK_WARN: | |
06ce7915 ÆAB |
30 | if (!option_strict) { |
31 | fprintf_ln(stderr, _("warning: tag input does not pass fsck: %s"), message); | |
32 | return 0; | |
33 | ||
34 | } | |
35 | /* fallthrough */ | |
acf9de4c ÆAB |
36 | case FSCK_ERROR: |
37 | /* | |
38 | * We treat both warnings and errors as errors, things | |
39 | * like missing "tagger" lines are "only" warnings | |
40 | * under fsck, we've always considered them an error. | |
41 | */ | |
2aa9425f | 42 | fprintf_ln(stderr, _("error: tag input does not pass fsck: %s"), message); |
acf9de4c ÆAB |
43 | return 1; |
44 | default: | |
2aa9425f | 45 | BUG(_("%d (FSCK_IGNORE?) should never trigger this callback"), |
acf9de4c | 46 | msg_type); |
ec4465ad | 47 | } |
ec4465ad LT |
48 | } |
49 | ||
acf9de4c | 50 | static int verify_object_in_tag(struct object_id *tagged_oid, int *tagged_type) |
ec4465ad | 51 | { |
acf9de4c ÆAB |
52 | int ret; |
53 | enum object_type type; | |
54 | unsigned long size; | |
55 | void *buffer; | |
56 | const struct object_id *repl; | |
57 | ||
bc726bd0 ÆAB |
58 | buffer = repo_read_object_file(the_repository, tagged_oid, &type, |
59 | &size); | |
acf9de4c | 60 | if (!buffer) |
2aa9425f | 61 | die(_("could not read tagged object '%s'"), |
acf9de4c ÆAB |
62 | oid_to_hex(tagged_oid)); |
63 | if (type != *tagged_type) | |
2aa9425f | 64 | die(_("object '%s' tagged as '%s', but is a '%s' type"), |
acf9de4c ÆAB |
65 | oid_to_hex(tagged_oid), |
66 | type_name(*tagged_type), type_name(type)); | |
67 | ||
68 | repl = lookup_replace_object(the_repository, tagged_oid); | |
0f156dbb | 69 | ret = check_object_signature(the_repository, repl, buffer, size, |
44439c1c | 70 | *tagged_type); |
acf9de4c | 71 | free(buffer); |
c818566d | 72 | |
acf9de4c | 73 | return ret; |
ec4465ad LT |
74 | } |
75 | ||
112dd514 | 76 | int cmd_mktag(int argc, const char **argv, const char *prefix) |
ec4465ad | 77 | { |
3f390a36 | 78 | static struct option builtin_mktag_options[] = { |
06ce7915 ÆAB |
79 | OPT_BOOL(0, "strict", &option_strict, |
80 | N_("enable more strict checking")), | |
3f390a36 ÆAB |
81 | OPT_END(), |
82 | }; | |
f285a2d7 | 83 | struct strbuf buf = STRBUF_INIT; |
acf9de4c ÆAB |
84 | struct object_id tagged_oid; |
85 | int tagged_type; | |
a09c985e | 86 | struct object_id result; |
ec4465ad | 87 | |
836c8ceb | 88 | argc = parse_options(argc, argv, prefix, |
3f390a36 ÆAB |
89 | builtin_mktag_options, |
90 | builtin_mktag_usage, 0); | |
ec4465ad | 91 | |
dfe39487 | 92 | if (strbuf_read(&buf, 0, 0) < 0) |
2aa9425f | 93 | die_errno(_("could not read from stdin")); |
ec4465ad | 94 | |
acf9de4c | 95 | fsck_options.error_func = mktag_fsck_error_func; |
53692df2 ÆAB |
96 | fsck_set_msg_type_from_ids(&fsck_options, FSCK_MSG_EXTRA_HEADER_ENTRY, |
97 | FSCK_WARN); | |
acfc0133 | 98 | /* config might set fsck.extraHeaderEntry=* again */ |
fb79f5bf | 99 | git_config(git_fsck_config, &fsck_options); |
acf9de4c ÆAB |
100 | if (fsck_tag_standalone(NULL, buf.buf, buf.len, &fsck_options, |
101 | &tagged_oid, &tagged_type)) | |
2aa9425f | 102 | die(_("tag on stdin did not pass our strict fsck check")); |
acf9de4c | 103 | |
ee213de2 | 104 | if (verify_object_in_tag(&tagged_oid, &tagged_type) < 0) |
2aa9425f | 105 | die(_("tag on stdin did not refer to a valid object")); |
ec4465ad | 106 | |
c80d226a | 107 | if (write_object_file(buf.buf, buf.len, OBJ_TAG, &result) < 0) |
2aa9425f | 108 | die(_("unable to write tag file")); |
e7332f96 | 109 | |
fd17f5b5 | 110 | strbuf_release(&buf); |
40ef015a | 111 | puts(oid_to_hex(&result)); |
ec4465ad LT |
112 | return 0; |
113 | } |