6 #include "parse-options.h"
8 #include "repository.h"
13 * Basic handler for bundle files to connect repositories via sneakernet.
14 * Invocation must include action.
15 * This function can create a bundle or provide information on an existing
16 * bundle supporting "fetch", "pull", and "ls-remote".
19 #define BUILTIN_BUNDLE_CREATE_USAGE \
20 N_("git bundle create [-q | --quiet | --progress]\n" \
21 " [--version=<version>] <file> <git-rev-list-args>")
22 #define BUILTIN_BUNDLE_VERIFY_USAGE \
23 N_("git bundle verify [-q | --quiet] <file>")
24 #define BUILTIN_BUNDLE_LIST_HEADS_USAGE \
25 N_("git bundle list-heads <file> [<refname>...]")
26 #define BUILTIN_BUNDLE_UNBUNDLE_USAGE \
27 N_("git bundle unbundle [--progress] <file> [<refname>...]")
29 static char const * const builtin_bundle_usage
[] = {
30 BUILTIN_BUNDLE_CREATE_USAGE
,
31 BUILTIN_BUNDLE_VERIFY_USAGE
,
32 BUILTIN_BUNDLE_LIST_HEADS_USAGE
,
33 BUILTIN_BUNDLE_UNBUNDLE_USAGE
,
37 static const char * const builtin_bundle_create_usage
[] = {
38 BUILTIN_BUNDLE_CREATE_USAGE
,
42 static const char * const builtin_bundle_verify_usage
[] = {
43 BUILTIN_BUNDLE_VERIFY_USAGE
,
47 static const char * const builtin_bundle_list_heads_usage
[] = {
48 BUILTIN_BUNDLE_LIST_HEADS_USAGE
,
52 static const char * const builtin_bundle_unbundle_usage
[] = {
53 BUILTIN_BUNDLE_UNBUNDLE_USAGE
,
57 static int parse_options_cmd_bundle(int argc
,
60 const char * const usagestr
[],
61 const struct option options
[],
63 argc
= parse_options(argc
, argv
, NULL
, options
, usagestr
,
64 PARSE_OPT_STOP_AT_NON_OPTION
);
66 usage_msg_opt(_("need a <file> argument"), usagestr
, options
);
67 *bundle_file
= prefix_filename_except_for_dash(prefix
, argv
[0]);
71 static int cmd_bundle_create(int argc
, const char **argv
, const char *prefix
) {
72 int all_progress_implied
= 1;
73 int progress
= isatty(STDERR_FILENO
);
74 struct strvec pack_opts
;
77 struct option options
[] = {
78 OPT_SET_INT('q', "quiet", &progress
,
79 N_("do not show progress meter"), 0),
80 OPT_SET_INT(0, "progress", &progress
,
81 N_("show progress meter"), 1),
82 OPT_SET_INT_F(0, "all-progress", &progress
,
83 N_("historical; same as --progress"), 2,
85 OPT_HIDDEN_BOOL(0, "all-progress-implied",
86 &all_progress_implied
,
87 N_("historical; does nothing")),
88 OPT_INTEGER(0, "version", &version
,
89 N_("specify bundle format version")),
94 argc
= parse_options_cmd_bundle(argc
, argv
, prefix
,
95 builtin_bundle_create_usage
, options
, &bundle_file
);
96 /* bundle internals use argv[1] as further parameters */
98 strvec_init(&pack_opts
);
100 strvec_push(&pack_opts
, "--quiet");
101 else if (progress
== 1)
102 strvec_push(&pack_opts
, "--progress");
103 else if (progress
== 2)
104 strvec_push(&pack_opts
, "--all-progress");
105 if (progress
&& all_progress_implied
)
106 strvec_push(&pack_opts
, "--all-progress-implied");
108 if (!startup_info
->have_repository
)
109 die(_("Need a repository to create a bundle."));
110 ret
= !!create_bundle(the_repository
, bundle_file
, argc
, argv
, &pack_opts
, version
);
111 strvec_clear(&pack_opts
);
117 * Similar to read_bundle_header(), but handle "-" as stdin.
119 static int open_bundle(const char *path
, struct bundle_header
*header
,
122 if (!strcmp(path
, "-")) {
125 return read_bundle_header_fd(0, header
, "<stdin>");
130 return read_bundle_header(path
, header
);
133 static int cmd_bundle_verify(int argc
, const char **argv
, const char *prefix
) {
134 struct bundle_header header
= BUNDLE_HEADER_INIT
;
138 struct option options
[] = {
139 OPT_BOOL('q', "quiet", &quiet
,
140 N_("do not show bundle details")),
146 argc
= parse_options_cmd_bundle(argc
, argv
, prefix
,
147 builtin_bundle_verify_usage
, options
, &bundle_file
);
148 /* bundle internals use argv[1] as further parameters */
150 if ((bundle_fd
= open_bundle(bundle_file
, &header
, &name
)) < 0) {
155 if (verify_bundle(the_repository
, &header
,
156 quiet
? VERIFY_BUNDLE_QUIET
: VERIFY_BUNDLE_VERBOSE
)) {
161 fprintf(stderr
, _("%s is okay\n"), name
);
165 bundle_header_release(&header
);
169 static int cmd_bundle_list_heads(int argc
, const char **argv
, const char *prefix
) {
170 struct bundle_header header
= BUNDLE_HEADER_INIT
;
173 struct option options
[] = {
178 argc
= parse_options_cmd_bundle(argc
, argv
, prefix
,
179 builtin_bundle_list_heads_usage
, options
, &bundle_file
);
180 /* bundle internals use argv[1] as further parameters */
182 if ((bundle_fd
= open_bundle(bundle_file
, &header
, NULL
)) < 0) {
187 ret
= !!list_bundle_refs(&header
, argc
, argv
);
190 bundle_header_release(&header
);
194 static int cmd_bundle_unbundle(int argc
, const char **argv
, const char *prefix
) {
195 struct bundle_header header
= BUNDLE_HEADER_INIT
;
198 int progress
= isatty(2);
200 struct option options
[] = {
201 OPT_BOOL(0, "progress", &progress
,
202 N_("show progress meter")),
206 struct strvec extra_index_pack_args
= STRVEC_INIT
;
208 argc
= parse_options_cmd_bundle(argc
, argv
, prefix
,
209 builtin_bundle_unbundle_usage
, options
, &bundle_file
);
210 /* bundle internals use argv[1] as further parameters */
212 if ((bundle_fd
= open_bundle(bundle_file
, &header
, NULL
)) < 0) {
216 if (!startup_info
->have_repository
)
217 die(_("Need a repository to unbundle."));
219 strvec_pushl(&extra_index_pack_args
, "-v", "--progress-title",
220 _("Unbundling objects"), NULL
);
221 ret
= !!unbundle(the_repository
, &header
, bundle_fd
,
222 &extra_index_pack_args
, 0) ||
223 list_bundle_refs(&header
, argc
, argv
);
224 bundle_header_release(&header
);
230 int cmd_bundle(int argc
, const char **argv
, const char *prefix
)
232 parse_opt_subcommand_fn
*fn
= NULL
;
233 struct option options
[] = {
234 OPT_SUBCOMMAND("create", &fn
, cmd_bundle_create
),
235 OPT_SUBCOMMAND("verify", &fn
, cmd_bundle_verify
),
236 OPT_SUBCOMMAND("list-heads", &fn
, cmd_bundle_list_heads
),
237 OPT_SUBCOMMAND("unbundle", &fn
, cmd_bundle_unbundle
),
241 argc
= parse_options(argc
, argv
, prefix
, options
, builtin_bundle_usage
,
244 packet_trace_identity("bundle");
246 return !!fn(argc
, argv
, prefix
);