]>
Commit | Line | Data |
---|---|---|
baffc0e7 | 1 | #include "builtin.h" |
dbbcd44f | 2 | #include "strvec.h" |
73c3253d | 3 | #include "parse-options.h" |
2e0afafe | 4 | #include "cache.h" |
30415d50 | 5 | #include "bundle.h" |
2e0afafe JS |
6 | |
7 | /* | |
8 | * Basic handler for bundle files to connect repositories via sneakernet. | |
9 | * Invocation must include action. | |
10 | * This function can create a bundle or provide information on an existing | |
34baebce | 11 | * bundle supporting "fetch", "pull", and "ls-remote". |
2e0afafe JS |
12 | */ |
13 | ||
73c3253d | 14 | static const char * const builtin_bundle_usage[] = { |
79862b6b | 15 | N_("git bundle create [<options>] <file> <git-rev-list args>"), |
e0eba649 | 16 | N_("git bundle verify [<options>] <file>"), |
73c3253d RJ |
17 | N_("git bundle list-heads <file> [<refname>...]"), |
18 | N_("git bundle unbundle <file> [<refname>...]"), | |
19 | NULL | |
20 | }; | |
2e0afafe | 21 | |
73c3253d | 22 | static const char * const builtin_bundle_create_usage[] = { |
79862b6b | 23 | N_("git bundle create [<options>] <file> <git-rev-list args>"), |
73c3253d RJ |
24 | NULL |
25 | }; | |
26 | ||
27 | static const char * const builtin_bundle_verify_usage[] = { | |
e0eba649 | 28 | N_("git bundle verify [<options>] <file>"), |
73c3253d RJ |
29 | NULL |
30 | }; | |
31 | ||
32 | static const char * const builtin_bundle_list_heads_usage[] = { | |
33 | N_("git bundle list-heads <file> [<refname>...]"), | |
34 | NULL | |
35 | }; | |
36 | ||
37 | static const char * const builtin_bundle_unbundle_usage[] = { | |
38 | N_("git bundle unbundle <file> [<refname>...]"), | |
39 | NULL | |
40 | }; | |
41 | ||
42 | static int verbose; | |
43 | ||
44 | static int parse_options_cmd_bundle(int argc, | |
45 | const char **argv, | |
46 | const char* prefix, | |
47 | const char * const usagestr[], | |
48 | const struct option options[], | |
49 | const char **bundle_file) { | |
50 | int newargc; | |
51 | newargc = parse_options(argc, argv, NULL, options, usagestr, | |
52 | PARSE_OPT_STOP_AT_NON_OPTION); | |
53 | if (argc < 1) | |
54 | usage_with_options(usagestr, options); | |
55 | *bundle_file = prefix_filename(prefix, argv[0]); | |
56 | return newargc; | |
57 | } | |
58 | ||
59 | static int cmd_bundle_create(int argc, const char **argv, const char *prefix) { | |
79862b6b RJ |
60 | int all_progress_implied = 0; |
61 | int progress = isatty(STDERR_FILENO); | |
22f9b7f3 | 62 | struct strvec pack_opts; |
c5aecfc8 | 63 | int version = -1; |
79862b6b | 64 | |
73c3253d | 65 | struct option options[] = { |
79862b6b RJ |
66 | OPT_SET_INT('q', "quiet", &progress, |
67 | N_("do not show progress meter"), 0), | |
68 | OPT_SET_INT(0, "progress", &progress, | |
69 | N_("show progress meter"), 1), | |
70 | OPT_SET_INT(0, "all-progress", &progress, | |
71 | N_("show progress meter during object writing phase"), 2), | |
72 | OPT_BOOL(0, "all-progress-implied", | |
73 | &all_progress_implied, | |
74 | N_("similar to --all-progress when progress meter is shown")), | |
c5aecfc8 | 75 | OPT_INTEGER(0, "version", &version, |
76 | N_("specify bundle format version")), | |
73c3253d RJ |
77 | OPT_END() |
78 | }; | |
79 | const char* bundle_file; | |
80 | ||
81 | argc = parse_options_cmd_bundle(argc, argv, prefix, | |
82 | builtin_bundle_create_usage, options, &bundle_file); | |
83 | /* bundle internals use argv[1] as further parameters */ | |
84 | ||
22f9b7f3 | 85 | strvec_init(&pack_opts); |
79862b6b | 86 | if (progress == 0) |
22f9b7f3 | 87 | strvec_push(&pack_opts, "--quiet"); |
79862b6b | 88 | else if (progress == 1) |
22f9b7f3 | 89 | strvec_push(&pack_opts, "--progress"); |
79862b6b | 90 | else if (progress == 2) |
22f9b7f3 | 91 | strvec_push(&pack_opts, "--all-progress"); |
79862b6b | 92 | if (progress && all_progress_implied) |
22f9b7f3 | 93 | strvec_push(&pack_opts, "--all-progress-implied"); |
79862b6b | 94 | |
73c3253d RJ |
95 | if (!startup_info->have_repository) |
96 | die(_("Need a repository to create a bundle.")); | |
c5aecfc8 | 97 | return !!create_bundle(the_repository, bundle_file, argc, argv, &pack_opts, version); |
73c3253d RJ |
98 | } |
99 | ||
100 | static int cmd_bundle_verify(int argc, const char **argv, const char *prefix) { | |
2e0afafe | 101 | struct bundle_header header; |
2e0afafe | 102 | int bundle_fd = -1; |
e0eba649 | 103 | int quiet = 0; |
2e0afafe | 104 | |
73c3253d | 105 | struct option options[] = { |
e0eba649 RJ |
106 | OPT_BOOL('q', "quiet", &quiet, |
107 | N_("do not show bundle details")), | |
73c3253d RJ |
108 | OPT_END() |
109 | }; | |
110 | const char* bundle_file; | |
2e0afafe | 111 | |
73c3253d RJ |
112 | argc = parse_options_cmd_bundle(argc, argv, prefix, |
113 | builtin_bundle_verify_usage, options, &bundle_file); | |
114 | /* bundle internals use argv[1] as further parameters */ | |
2e0afafe | 115 | |
2e0afafe | 116 | memset(&header, 0, sizeof(header)); |
73c3253d | 117 | if ((bundle_fd = read_bundle_header(bundle_file, &header)) < 0) |
2e0afafe | 118 | return 1; |
73c3253d | 119 | close(bundle_fd); |
e0eba649 | 120 | if (verify_bundle(the_repository, &header, !quiet)) |
73c3253d RJ |
121 | return 1; |
122 | fprintf(stderr, _("%s is okay\n"), bundle_file); | |
123 | return 0; | |
124 | } | |
2e0afafe | 125 | |
73c3253d RJ |
126 | static int cmd_bundle_list_heads(int argc, const char **argv, const char *prefix) { |
127 | struct bundle_header header; | |
128 | int bundle_fd = -1; | |
129 | ||
130 | struct option options[] = { | |
131 | OPT_END() | |
132 | }; | |
133 | const char* bundle_file; | |
134 | ||
135 | argc = parse_options_cmd_bundle(argc, argv, prefix, | |
136 | builtin_bundle_list_heads_usage, options, &bundle_file); | |
137 | /* bundle internals use argv[1] as further parameters */ | |
138 | ||
139 | memset(&header, 0, sizeof(header)); | |
140 | if ((bundle_fd = read_bundle_header(bundle_file, &header)) < 0) | |
141 | return 1; | |
142 | close(bundle_fd); | |
143 | return !!list_bundle_refs(&header, argc, argv); | |
144 | } | |
145 | ||
146 | static int cmd_bundle_unbundle(int argc, const char **argv, const char *prefix) { | |
147 | struct bundle_header header; | |
148 | int bundle_fd = -1; | |
149 | ||
150 | struct option options[] = { | |
151 | OPT_END() | |
152 | }; | |
153 | const char* bundle_file; | |
154 | ||
155 | argc = parse_options_cmd_bundle(argc, argv, prefix, | |
156 | builtin_bundle_unbundle_usage, options, &bundle_file); | |
157 | /* bundle internals use argv[1] as further parameters */ | |
158 | ||
159 | memset(&header, 0, sizeof(header)); | |
160 | if ((bundle_fd = read_bundle_header(bundle_file, &header)) < 0) | |
161 | return 1; | |
162 | if (!startup_info->have_repository) | |
163 | die(_("Need a repository to unbundle.")); | |
164 | return !!unbundle(the_repository, &header, bundle_fd, 0) || | |
165 | list_bundle_refs(&header, argc, argv); | |
166 | } | |
167 | ||
168 | int cmd_bundle(int argc, const char **argv, const char *prefix) | |
169 | { | |
170 | struct option options[] = { | |
171 | OPT__VERBOSE(&verbose, N_("be verbose; must be placed before a subcommand")), | |
172 | OPT_END() | |
173 | }; | |
174 | int result; | |
175 | ||
176 | argc = parse_options(argc, argv, prefix, options, builtin_bundle_usage, | |
177 | PARSE_OPT_STOP_AT_NON_OPTION); | |
178 | ||
179 | packet_trace_identity("bundle"); | |
180 | ||
181 | if (argc < 2) | |
182 | usage_with_options(builtin_bundle_usage, options); | |
183 | ||
184 | else if (!strcmp(argv[0], "create")) | |
185 | result = cmd_bundle_create(argc, argv, prefix); | |
186 | else if (!strcmp(argv[0], "verify")) | |
187 | result = cmd_bundle_verify(argc, argv, prefix); | |
188 | else if (!strcmp(argv[0], "list-heads")) | |
189 | result = cmd_bundle_list_heads(argc, argv, prefix); | |
190 | else if (!strcmp(argv[0], "unbundle")) | |
191 | result = cmd_bundle_unbundle(argc, argv, prefix); | |
192 | else { | |
193 | error(_("Unknown subcommand: %s"), argv[0]); | |
194 | usage_with_options(builtin_bundle_usage, options); | |
2e0afafe | 195 | } |
73c3253d | 196 | return result ? 1 : 0; |
2e0afafe | 197 | } |