bundle: framework for options before bundle file
Make it possible for any of the git-bundle subcommands to include options: - before the sub-command - after the sub-command, before the bundle filename There is an immediate gain in support for help with all of the sub-commands, where 'git bundle list-heads -h' previously returned an error. Downside here is an increase in code duplication that cannot be trivially avoided short of shared global static options. Signed-off-by: Robin H. Johnson <robbat2@gentoo.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Robin H. Johnson committed
Nov 10, 2019 at 12:41 UTC
73c3253d75e1268946834e72147481fc9a66cc90
1 file changed
+145
-45
builtin/bundle.c
+145
-45
@@ -1,4 +1,5 @@
1
#include "builtin.h"
2
+#include "parse-options.h"
3
#include "cache.h"
4
#include "bundle.h"
5
@@ -9,59 +10,158 @@
10
* bundle supporting "fetch", "pull", and "ls-remote".
11
*/
12
12
-static const char builtin_bundle_usage[] =
13
- "git bundle create <file> <git-rev-list args>\n"
14
- " or: git bundle verify <file>\n"
15
- " or: git bundle list-heads <file> [<refname>...]\n"
16
- " or: git bundle unbundle <file> [<refname>...]";
13
+static const char * const builtin_bundle_usage[] = {
14
+ N_("git bundle create <file> <git-rev-list args>"),
15
+ N_("git bundle verify <file>"),
16
+ N_("git bundle list-heads <file> [<refname>...]"),
17
+ N_("git bundle unbundle <file> [<refname>...]"),
18
+ NULL
19
+};
20
18
-int cmd_bundle(int argc, const char **argv, const char *prefix)
19
-{
21
+static const char * const builtin_bundle_create_usage[] = {
22
+ N_("git bundle create <file> <git-rev-list args>"),
23
+ NULL
24
+};
25
+
26
+static const char * const builtin_bundle_verify_usage[] = {
27
+ N_("git bundle verify <file>"),
28
+ NULL
29
+};
30
+
31
+static const char * const builtin_bundle_list_heads_usage[] = {
32
+ N_("git bundle list-heads <file> [<refname>...]"),
33
+ NULL
34
+};
35
+
36
+static const char * const builtin_bundle_unbundle_usage[] = {
37
+ N_("git bundle unbundle <file> [<refname>...]"),
38
+ NULL
39
+};
40
+
41
+static int verbose;
42
+
43
+static int parse_options_cmd_bundle(int argc,
44
+ const char **argv,
45
+ const char* prefix,
46
+ const char * const usagestr[],
47
+ const struct option options[],
48
+ const char **bundle_file) {
49
+ int newargc;
50
+ newargc = parse_options(argc, argv, NULL, options, usagestr,
51
+ PARSE_OPT_STOP_AT_NON_OPTION);
52
+ if (argc < 1)
53
+ usage_with_options(usagestr, options);
54
+ *bundle_file = prefix_filename(prefix, argv[0]);
55
+ return newargc;
56
+}
57
+
58
+static int cmd_bundle_create(int argc, const char **argv, const char *prefix) {
59
+ struct option options[] = {
60
+ OPT_END()
61
+ };
62
+ const char* bundle_file;
63
+
64
+ argc = parse_options_cmd_bundle(argc, argv, prefix,
65
+ builtin_bundle_create_usage, options, &bundle_file);
66
+ /* bundle internals use argv[1] as further parameters */
67
+
68
+ if (!startup_info->have_repository)
69
+ die(_("Need a repository to create a bundle."));
70
+ return !!create_bundle(the_repository, bundle_file, argc, argv);
71
+}
72
+
73
+static int cmd_bundle_verify(int argc, const char **argv, const char *prefix) {
74
struct bundle_header header;
21
- const char *cmd, *bundle_file;
75
int bundle_fd = -1;
76
24
- if (argc < 3)
25
- usage(builtin_bundle_usage);
77
+ struct option options[] = {
78
+ OPT_END()
79
+ };
80
+ const char* bundle_file;
81
27
- cmd = argv[1];
28
- bundle_file = prefix_filename(prefix, argv[2]);
29
- argc -= 2;
30
- argv += 2;
82
+ argc = parse_options_cmd_bundle(argc, argv, prefix,
83
+ builtin_bundle_verify_usage, options, &bundle_file);
84
+ /* bundle internals use argv[1] as further parameters */
85
86
memset(&header, 0, sizeof(header));
33
- if (strcmp(cmd, "create") && (bundle_fd =
34
- read_bundle_header(bundle_file, &header)) < 0)
87
+ if ((bundle_fd = read_bundle_header(bundle_file, &header)) < 0)
88
return 1;
89
+ close(bundle_fd);
90
+ if (verify_bundle(the_repository, &header, 1))
91
+ return 1;
92
+ fprintf(stderr, _("%s is okay\n"), bundle_file);
93
+ return 0;
94
+}
95
37
- if (!strcmp(cmd, "verify")) {
38
- close(bundle_fd);
39
- if (argc != 1) {
40
- usage(builtin_bundle_usage);
41
- return 1;
42
- }
43
- if (verify_bundle(the_repository, &header, 1))
44
- return 1;
45
- fprintf(stderr, _("%s is okay\n"), bundle_file);
46
- return 0;
47
- }
48
- if (!strcmp(cmd, "list-heads")) {
49
- close(bundle_fd);
50
- return !!list_bundle_refs(&header, argc, argv);
96
+static int cmd_bundle_list_heads(int argc, const char **argv, const char *prefix) {
97
+ struct bundle_header header;
98
+ int bundle_fd = -1;
99
+
100
+ struct option options[] = {
101
+ OPT_END()
102
+ };
103
+ const char* bundle_file;
104
+
105
+ argc = parse_options_cmd_bundle(argc, argv, prefix,
106
+ builtin_bundle_list_heads_usage, options, &bundle_file);
107
+ /* bundle internals use argv[1] as further parameters */
108
+
109
+ memset(&header, 0, sizeof(header));
110
+ if ((bundle_fd = read_bundle_header(bundle_file, &header)) < 0)
111
+ return 1;
112
+ close(bundle_fd);
113
+ return !!list_bundle_refs(&header, argc, argv);
114
+}
115
+
116
+static int cmd_bundle_unbundle(int argc, const char **argv, const char *prefix) {
117
+ struct bundle_header header;
118
+ int bundle_fd = -1;
119
+
120
+ struct option options[] = {
121
+ OPT_END()
122
+ };
123
+ const char* bundle_file;
124
+
125
+ argc = parse_options_cmd_bundle(argc, argv, prefix,
126
+ builtin_bundle_unbundle_usage, options, &bundle_file);
127
+ /* bundle internals use argv[1] as further parameters */
128
+
129
+ memset(&header, 0, sizeof(header));
130
+ if ((bundle_fd = read_bundle_header(bundle_file, &header)) < 0)
131
+ return 1;
132
+ if (!startup_info->have_repository)
133
+ die(_("Need a repository to unbundle."));
134
+ return !!unbundle(the_repository, &header, bundle_fd, 0) ||
135
+ list_bundle_refs(&header, argc, argv);
136
+}
137
+
138
+int cmd_bundle(int argc, const char **argv, const char *prefix)
139
+{
140
+ struct option options[] = {
141
+ OPT__VERBOSE(&verbose, N_("be verbose; must be placed before a subcommand")),
142
+ OPT_END()
143
+ };
144
+ int result;
145
+
146
+ argc = parse_options(argc, argv, prefix, options, builtin_bundle_usage,
147
+ PARSE_OPT_STOP_AT_NON_OPTION);
148
+
149
+ packet_trace_identity("bundle");
150
+
151
+ if (argc < 2)
152
+ usage_with_options(builtin_bundle_usage, options);
153
+
154
+ else if (!strcmp(argv[0], "create"))
155
+ result = cmd_bundle_create(argc, argv, prefix);
156
+ else if (!strcmp(argv[0], "verify"))
157
+ result = cmd_bundle_verify(argc, argv, prefix);
158
+ else if (!strcmp(argv[0], "list-heads"))
159
+ result = cmd_bundle_list_heads(argc, argv, prefix);
160
+ else if (!strcmp(argv[0], "unbundle"))
161
+ result = cmd_bundle_unbundle(argc, argv, prefix);
162
+ else {
163
+ error(_("Unknown subcommand: %s"), argv[0]);
164
+ usage_with_options(builtin_bundle_usage, options);
165
}
52
- if (!strcmp(cmd, "create")) {
53
- if (argc < 2) {
54
- usage(builtin_bundle_usage);
55
- return 1;
56
- }
57
- if (!startup_info->have_repository)
58
- die(_("Need a repository to create a bundle."));
59
- return !!create_bundle(the_repository, bundle_file, argc, argv);
60
- } else if (!strcmp(cmd, "unbundle")) {
61
- if (!startup_info->have_repository)
62
- die(_("Need a repository to unbundle."));
63
- return !!unbundle(the_repository, &header, bundle_fd, 0) ||
64
- list_bundle_refs(&header, argc, argv);
65
- } else
66
- usage(builtin_bundle_usage);
166
+ return result ? 1 : 0;
167
}