Skip to content

Commit c48ff9a

Browse files
committed
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 <[email protected]>
1 parent 566a143 commit c48ff9a

File tree

1 file changed

+145
-45
lines changed

1 file changed

+145
-45
lines changed

builtin/bundle.c

Lines changed: 145 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "builtin.h"
2+
#include "parse-options.h"
23
#include "cache.h"
34
#include "bundle.h"
45

@@ -9,59 +10,158 @@
910
* bundle supporting "fetch", "pull", and "ls-remote".
1011
*/
1112

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+
};
1720

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) {
2074
struct bundle_header header;
21-
const char *cmd, *bundle_file;
2275
int bundle_fd = -1;
2376

24-
if (argc < 3)
25-
usage(builtin_bundle_usage);
77+
struct option options[] = {
78+
OPT_END()
79+
};
80+
const char* bundle_file;
2681

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 */
3185

3286
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)
3588
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+
}
3695

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);
51165
}
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;
67167
}

0 commit comments

Comments
 (0)