12
#include "builtin.h"
13
#include "utf8.h"
14
#include "gpg-interface.h"
15
+#include "parse-options.h"
16
16
-static const char commit_tree_usage[] = "git commit-tree [(-p <sha1>)...] [-S[<keyid>]] [-m <message>] [-F <file>] <sha1>";
17
+static const char * const commit_tree_usage[] = {
18
+ N_("git commit-tree [(-p <parent>)...] [-S[<keyid>]] [(-m <message>)...] "
19
+ "[(-F <file>)...] <tree>"),
20
+ NULL
21
+};
22
23
static const char *sign_commit;
24
28
struct commit_list *parents;
29
for (parents = *parents_p; parents; parents = parents->next) {
30
if (parents->item == parent) {
26
- error("duplicate parent %s ignored", oid_to_hex(oid));
31
+ error(_("duplicate parent %s ignored"), oid_to_hex(oid));
32
return;
33
}
34
parents_p = &parents->next;
44
return git_default_config(var, value, cb);
45
}
46
47
+static int parse_parent_arg_callback(const struct option *opt,
48
+ const char *arg, int unset)
49
+{
50
+ struct object_id oid;
51
+ struct commit_list **parents = opt->value;
52
+
53
+ BUG_ON_OPT_NEG_NOARG(unset, arg);
54
+
55
+ if (get_oid_commit(arg, &oid))
56
+ die(_("not a valid object name %s"), arg);
57
+
58
+ assert_oid_type(&oid, OBJ_COMMIT);
59
+ new_parent(lookup_commit(the_repository, &oid), parents);
60
+ return 0;
61
+}
62
+
63
+static int parse_message_arg_callback(const struct option *opt,
64
+ const char *arg, int unset)
65
+{
66
+ struct strbuf *buf = opt->value;
67
+
68
+ BUG_ON_OPT_NEG_NOARG(unset, arg);
69
+
70
+ if (buf->len)
71
+ strbuf_addch(buf, '\n');
72
+ strbuf_addstr(buf, arg);
73
+ strbuf_complete_line(buf);
74
+
75
+ return 0;
76
+}
77
+
78
+static int parse_file_arg_callback(const struct option *opt,
79
+ const char *arg, int unset)
80
+{
81
+ int fd;
82
+ struct strbuf *buf = opt->value;
83
+
84
+ BUG_ON_OPT_NEG_NOARG(unset, arg);
85
+
86
+ if (buf->len)
87
+ strbuf_addch(buf, '\n');
88
+ if (!strcmp(arg, "-"))
89
+ fd = 0;
90
+ else {
91
+ fd = open(arg, O_RDONLY);
92
+ if (fd < 0)
93
+ die_errno(_("git commit-tree: failed to open '%s'"), arg);
94
+ }
95
+ if (strbuf_read(buf, fd, 0) < 0)
96
+ die_errno(_("git commit-tree: failed to read '%s'"), arg);
97
+ if (fd && close(fd))
98
+ die_errno(_("git commit-tree: failed to close '%s'"), arg);
99
+
100
+ return 0;
101
+}
102
+
103
int cmd_commit_tree(int argc, const char **argv, const char *prefix)
104
{
44
- int i, got_tree = 0;
105
+ static struct strbuf buffer = STRBUF_INIT;
106
struct commit_list *parents = NULL;
107
struct object_id tree_oid;
108
struct object_id commit_oid;
48
- struct strbuf buffer = STRBUF_INIT;
109
+
110
+ struct option options[] = {
111
+ { OPTION_CALLBACK, 'p', NULL, &parents, N_("parent"),
112
+ N_("id of a parent commit object"), PARSE_OPT_NONEG,
113
+ parse_parent_arg_callback },
114
+ { OPTION_CALLBACK, 'm', NULL, &buffer, N_("message"),
115
+ N_("commit message"), PARSE_OPT_NONEG,
116
+ parse_message_arg_callback },
117
+ { OPTION_CALLBACK, 'F', NULL, &buffer, N_("file"),
118
+ N_("read commit log message from file"), PARSE_OPT_NONEG,
119
+ parse_file_arg_callback },
120
+ { OPTION_STRING, 'S', "gpg-sign", &sign_commit, N_("key-id"),
121
+ N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
122
+ OPT_END()
123
+ };
124
125
git_config(commit_tree_config, NULL);
126
127
if (argc < 2 || !strcmp(argv[1], "-h"))
53
- usage(commit_tree_usage);
54
-
55
- for (i = 1; i < argc; i++) {
56
- const char *arg = argv[i];
57
- if (!strcmp(arg, "-p")) {
58
- struct object_id oid;
59
- if (argc <= ++i)
60
- usage(commit_tree_usage);
61
- if (get_oid_commit(argv[i], &oid))
62
- die("Not a valid object name %s", argv[i]);
63
- assert_oid_type(&oid, OBJ_COMMIT);
64
- new_parent(lookup_commit(the_repository, &oid),
65
- &parents);
66
- continue;
67
- }
128
+ usage_with_options(commit_tree_usage, options);
129
69
- if (!strcmp(arg, "--gpg-sign")) {
70
- sign_commit = "";
71
- continue;
72
- }
130
+ argc = parse_options(argc, argv, prefix, options, commit_tree_usage, 0);
131
74
- if (skip_prefix(arg, "-S", &sign_commit) ||
75
- skip_prefix(arg, "--gpg-sign=", &sign_commit))
76
- continue;
132
+ if (argc != 1)
133
+ die(_("must give exactly one tree"));
134
78
- if (!strcmp(arg, "--no-gpg-sign")) {
79
- sign_commit = NULL;
80
- continue;
81
- }
82
-
83
- if (!strcmp(arg, "-m")) {
84
- if (argc <= ++i)
85
- usage(commit_tree_usage);
86
- if (buffer.len)
87
- strbuf_addch(&buffer, '\n');
88
- strbuf_addstr(&buffer, argv[i]);
89
- strbuf_complete_line(&buffer);
90
- continue;
91
- }
92
-
93
- if (!strcmp(arg, "-F")) {
94
- int fd;
95
-
96
- if (argc <= ++i)
97
- usage(commit_tree_usage);
98
- if (buffer.len)
99
- strbuf_addch(&buffer, '\n');
100
- if (!strcmp(argv[i], "-"))
101
- fd = 0;
102
- else {
103
- fd = open(argv[i], O_RDONLY);
104
- if (fd < 0)
105
- die_errno("git commit-tree: failed to open '%s'",
106
- argv[i]);
107
- }
108
- if (strbuf_read(&buffer, fd, 0) < 0)
109
- die_errno("git commit-tree: failed to read '%s'",
110
- argv[i]);
111
- if (fd && close(fd))
112
- die_errno("git commit-tree: failed to close '%s'",
113
- argv[i]);
114
- continue;
115
- }
116
-
117
- if (get_oid_tree(arg, &tree_oid))
118
- die("Not a valid object name %s", arg);
119
- if (got_tree)
120
- die("Cannot give more than one trees");
121
- got_tree = 1;
122
- }
135
+ if (get_oid_tree(argv[0], &tree_oid))
136
+ die(_("not a valid object name %s"), argv[0]);
137
138
if (!buffer.len) {
139
if (strbuf_read(&buffer, 0, 0) < 0)
126
- die_errno("git commit-tree: failed to read");
140
+ die_errno(_("git commit-tree: failed to read"));
141
}
142
143
if (commit_tree(buffer.buf, buffer.len, &tree_oid, parents, &commit_oid,