]> git.ipfire.org Git - thirdparty/git.git/blob - builtin/mktag.c
Merge branch 'bb/unicode-width-table-15'
[thirdparty/git.git] / builtin / mktag.c
1 #include "builtin.h"
2 #include "gettext.h"
3 #include "hex.h"
4 #include "parse-options.h"
5 #include "strbuf.h"
6 #include "tag.h"
7 #include "replace-object.h"
8 #include "object-file.h"
9 #include "object-store-ll.h"
10 #include "fsck.h"
11 #include "config.h"
12
13 static char const * const builtin_mktag_usage[] = {
14 "git mktag",
15 NULL
16 };
17 static int option_strict = 1;
18
19 static struct fsck_options fsck_options = FSCK_OPTIONS_STRICT;
20
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,
24 enum fsck_msg_type msg_type,
25 enum fsck_msg_id msg_id UNUSED,
26 const char *message)
27 {
28 switch (msg_type) {
29 case FSCK_WARN:
30 if (!option_strict) {
31 fprintf_ln(stderr, _("warning: tag input does not pass fsck: %s"), message);
32 return 0;
33
34 }
35 /* fallthrough */
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 */
42 fprintf_ln(stderr, _("error: tag input does not pass fsck: %s"), message);
43 return 1;
44 default:
45 BUG(_("%d (FSCK_IGNORE?) should never trigger this callback"),
46 msg_type);
47 }
48 }
49
50 static int verify_object_in_tag(struct object_id *tagged_oid, int *tagged_type)
51 {
52 int ret;
53 enum object_type type;
54 unsigned long size;
55 void *buffer;
56 const struct object_id *repl;
57
58 buffer = repo_read_object_file(the_repository, tagged_oid, &type,
59 &size);
60 if (!buffer)
61 die(_("could not read tagged object '%s'"),
62 oid_to_hex(tagged_oid));
63 if (type != *tagged_type)
64 die(_("object '%s' tagged as '%s', but is a '%s' type"),
65 oid_to_hex(tagged_oid),
66 type_name(*tagged_type), type_name(type));
67
68 repl = lookup_replace_object(the_repository, tagged_oid);
69 ret = check_object_signature(the_repository, repl, buffer, size,
70 *tagged_type);
71 free(buffer);
72
73 return ret;
74 }
75
76 int cmd_mktag(int argc, const char **argv, const char *prefix)
77 {
78 static struct option builtin_mktag_options[] = {
79 OPT_BOOL(0, "strict", &option_strict,
80 N_("enable more strict checking")),
81 OPT_END(),
82 };
83 struct strbuf buf = STRBUF_INIT;
84 struct object_id tagged_oid;
85 int tagged_type;
86 struct object_id result;
87
88 argc = parse_options(argc, argv, prefix,
89 builtin_mktag_options,
90 builtin_mktag_usage, 0);
91
92 if (strbuf_read(&buf, 0, 0) < 0)
93 die_errno(_("could not read from stdin"));
94
95 fsck_options.error_func = mktag_fsck_error_func;
96 fsck_set_msg_type_from_ids(&fsck_options, FSCK_MSG_EXTRA_HEADER_ENTRY,
97 FSCK_WARN);
98 /* config might set fsck.extraHeaderEntry=* again */
99 git_config(git_fsck_config, &fsck_options);
100 if (fsck_tag_standalone(NULL, buf.buf, buf.len, &fsck_options,
101 &tagged_oid, &tagged_type))
102 die(_("tag on stdin did not pass our strict fsck check"));
103
104 if (verify_object_in_tag(&tagged_oid, &tagged_type) < 0)
105 die(_("tag on stdin did not refer to a valid object"));
106
107 if (write_object_file(buf.buf, buf.len, OBJ_TAG, &result) < 0)
108 die(_("unable to write tag file"));
109
110 strbuf_release(&buf);
111 puts(oid_to_hex(&result));
112 return 0;
113 }