]>
Commit | Line | Data |
---|---|---|
baffc0e7 | 1 | #include "builtin.h" |
79862b6b | 2 | #include "argv-array.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); | |
62 | struct argv_array pack_opts; | |
63 | ||
73c3253d | 64 | struct option options[] = { |
79862b6b RJ |
65 | OPT_SET_INT('q', "quiet", &progress, |
66 | N_("do not show progress meter"), 0), | |
67 | OPT_SET_INT(0, "progress", &progress, | |
68 | N_("show progress meter"), 1), | |
69 | OPT_SET_INT(0, "all-progress", &progress, | |
70 | N_("show progress meter during object writing phase"), 2), | |
71 | OPT_BOOL(0, "all-progress-implied", | |
72 | &all_progress_implied, | |
73 | N_("similar to --all-progress when progress meter is shown")), | |
73c3253d RJ |
74 | OPT_END() |
75 | }; | |
76 | const char* bundle_file; | |
77 | ||
78 | argc = parse_options_cmd_bundle(argc, argv, prefix, | |
79 | builtin_bundle_create_usage, options, &bundle_file); | |
80 | /* bundle internals use argv[1] as further parameters */ | |
81 | ||
79862b6b RJ |
82 | argv_array_init(&pack_opts); |
83 | if (progress == 0) | |
84 | argv_array_push(&pack_opts, "--quiet"); | |
85 | else if (progress == 1) | |
86 | argv_array_push(&pack_opts, "--progress"); | |
87 | else if (progress == 2) | |
88 | argv_array_push(&pack_opts, "--all-progress"); | |
89 | if (progress && all_progress_implied) | |
90 | argv_array_push(&pack_opts, "--all-progress-implied"); | |
91 | ||
73c3253d RJ |
92 | if (!startup_info->have_repository) |
93 | die(_("Need a repository to create a bundle.")); | |
79862b6b | 94 | return !!create_bundle(the_repository, bundle_file, argc, argv, &pack_opts); |
73c3253d RJ |
95 | } |
96 | ||
97 | static int cmd_bundle_verify(int argc, const char **argv, const char *prefix) { | |
2e0afafe | 98 | struct bundle_header header; |
2e0afafe | 99 | int bundle_fd = -1; |
e0eba649 | 100 | int quiet = 0; |
2e0afafe | 101 | |
73c3253d | 102 | struct option options[] = { |
e0eba649 RJ |
103 | OPT_BOOL('q', "quiet", &quiet, |
104 | N_("do not show bundle details")), | |
73c3253d RJ |
105 | OPT_END() |
106 | }; | |
107 | const char* bundle_file; | |
2e0afafe | 108 | |
73c3253d RJ |
109 | argc = parse_options_cmd_bundle(argc, argv, prefix, |
110 | builtin_bundle_verify_usage, options, &bundle_file); | |
111 | /* bundle internals use argv[1] as further parameters */ | |
2e0afafe | 112 | |
2e0afafe | 113 | memset(&header, 0, sizeof(header)); |
73c3253d | 114 | if ((bundle_fd = read_bundle_header(bundle_file, &header)) < 0) |
2e0afafe | 115 | return 1; |
73c3253d | 116 | close(bundle_fd); |
e0eba649 | 117 | if (verify_bundle(the_repository, &header, !quiet)) |
73c3253d RJ |
118 | return 1; |
119 | fprintf(stderr, _("%s is okay\n"), bundle_file); | |
120 | return 0; | |
121 | } | |
2e0afafe | 122 | |
73c3253d RJ |
123 | static int cmd_bundle_list_heads(int argc, const char **argv, const char *prefix) { |
124 | struct bundle_header header; | |
125 | int bundle_fd = -1; | |
126 | ||
127 | struct option options[] = { | |
128 | OPT_END() | |
129 | }; | |
130 | const char* bundle_file; | |
131 | ||
132 | argc = parse_options_cmd_bundle(argc, argv, prefix, | |
133 | builtin_bundle_list_heads_usage, options, &bundle_file); | |
134 | /* bundle internals use argv[1] as further parameters */ | |
135 | ||
136 | memset(&header, 0, sizeof(header)); | |
137 | if ((bundle_fd = read_bundle_header(bundle_file, &header)) < 0) | |
138 | return 1; | |
139 | close(bundle_fd); | |
140 | return !!list_bundle_refs(&header, argc, argv); | |
141 | } | |
142 | ||
143 | static int cmd_bundle_unbundle(int argc, const char **argv, const char *prefix) { | |
144 | struct bundle_header header; | |
145 | int bundle_fd = -1; | |
146 | ||
147 | struct option options[] = { | |
148 | OPT_END() | |
149 | }; | |
150 | const char* bundle_file; | |
151 | ||
152 | argc = parse_options_cmd_bundle(argc, argv, prefix, | |
153 | builtin_bundle_unbundle_usage, options, &bundle_file); | |
154 | /* bundle internals use argv[1] as further parameters */ | |
155 | ||
156 | memset(&header, 0, sizeof(header)); | |
157 | if ((bundle_fd = read_bundle_header(bundle_file, &header)) < 0) | |
158 | return 1; | |
159 | if (!startup_info->have_repository) | |
160 | die(_("Need a repository to unbundle.")); | |
161 | return !!unbundle(the_repository, &header, bundle_fd, 0) || | |
162 | list_bundle_refs(&header, argc, argv); | |
163 | } | |
164 | ||
165 | int cmd_bundle(int argc, const char **argv, const char *prefix) | |
166 | { | |
167 | struct option options[] = { | |
168 | OPT__VERBOSE(&verbose, N_("be verbose; must be placed before a subcommand")), | |
169 | OPT_END() | |
170 | }; | |
171 | int result; | |
172 | ||
173 | argc = parse_options(argc, argv, prefix, options, builtin_bundle_usage, | |
174 | PARSE_OPT_STOP_AT_NON_OPTION); | |
175 | ||
176 | packet_trace_identity("bundle"); | |
177 | ||
178 | if (argc < 2) | |
179 | usage_with_options(builtin_bundle_usage, options); | |
180 | ||
181 | else if (!strcmp(argv[0], "create")) | |
182 | result = cmd_bundle_create(argc, argv, prefix); | |
183 | else if (!strcmp(argv[0], "verify")) | |
184 | result = cmd_bundle_verify(argc, argv, prefix); | |
185 | else if (!strcmp(argv[0], "list-heads")) | |
186 | result = cmd_bundle_list_heads(argc, argv, prefix); | |
187 | else if (!strcmp(argv[0], "unbundle")) | |
188 | result = cmd_bundle_unbundle(argc, argv, prefix); | |
189 | else { | |
190 | error(_("Unknown subcommand: %s"), argv[0]); | |
191 | usage_with_options(builtin_bundle_usage, options); | |
2e0afafe | 192 | } |
73c3253d | 193 | return result ? 1 : 0; |
2e0afafe | 194 | } |