Git fork
at reftables-rust 326 lines 9.0 kB view raw
1#define USE_THE_REPOSITORY_VARIABLE 2#include "builtin.h" 3#include "abspath.h" 4#include "config.h" 5#include "environment.h" 6#include "gettext.h" 7#include "parse-options.h" 8#include "midx.h" 9#include "strbuf.h" 10#include "trace2.h" 11#include "odb.h" 12#include "replace-object.h" 13#include "repository.h" 14 15#define BUILTIN_MIDX_WRITE_USAGE \ 16 N_("git multi-pack-index [<options>] write [--preferred-pack=<pack>]" \ 17 "[--refs-snapshot=<path>]") 18 19#define BUILTIN_MIDX_VERIFY_USAGE \ 20 N_("git multi-pack-index [<options>] verify") 21 22#define BUILTIN_MIDX_EXPIRE_USAGE \ 23 N_("git multi-pack-index [<options>] expire") 24 25#define BUILTIN_MIDX_REPACK_USAGE \ 26 N_("git multi-pack-index [<options>] repack [--batch-size=<size>]") 27 28static char const * const builtin_multi_pack_index_write_usage[] = { 29 BUILTIN_MIDX_WRITE_USAGE, 30 NULL 31}; 32static char const * const builtin_multi_pack_index_verify_usage[] = { 33 BUILTIN_MIDX_VERIFY_USAGE, 34 NULL 35}; 36static char const * const builtin_multi_pack_index_expire_usage[] = { 37 BUILTIN_MIDX_EXPIRE_USAGE, 38 NULL 39}; 40static char const * const builtin_multi_pack_index_repack_usage[] = { 41 BUILTIN_MIDX_REPACK_USAGE, 42 NULL 43}; 44static char const * const builtin_multi_pack_index_usage[] = { 45 BUILTIN_MIDX_WRITE_USAGE, 46 BUILTIN_MIDX_VERIFY_USAGE, 47 BUILTIN_MIDX_EXPIRE_USAGE, 48 BUILTIN_MIDX_REPACK_USAGE, 49 NULL 50}; 51 52static struct opts_multi_pack_index { 53 char *object_dir; 54 const char *preferred_pack; 55 char *refs_snapshot; 56 unsigned long batch_size; 57 unsigned flags; 58 int stdin_packs; 59} opts; 60 61 62static int parse_object_dir(const struct option *opt, const char *arg, 63 int unset) 64{ 65 char **value = opt->value; 66 free(*value); 67 if (unset) 68 *value = xstrdup(the_repository->objects->sources->path); 69 else 70 *value = real_pathdup(arg, 1); 71 return 0; 72} 73 74static struct odb_source *handle_object_dir_option(struct repository *repo) 75{ 76 struct odb_source *source = odb_find_source(repo->objects, opts.object_dir); 77 if (!source) 78 source = odb_add_to_alternates_memory(repo->objects, opts.object_dir); 79 return source; 80} 81 82static struct option common_opts[] = { 83 OPT_CALLBACK(0, "object-dir", &opts.object_dir, 84 N_("directory"), 85 N_("object directory containing set of packfile and pack-index pairs"), 86 parse_object_dir), 87 OPT_END(), 88}; 89 90static struct option *add_common_options(struct option *prev) 91{ 92 return parse_options_concat(common_opts, prev); 93} 94 95static int git_multi_pack_index_write_config(const char *var, const char *value, 96 const struct config_context *ctx UNUSED, 97 void *cb UNUSED) 98{ 99 if (!strcmp(var, "pack.writebitmaphashcache")) { 100 if (git_config_bool(var, value)) 101 opts.flags |= MIDX_WRITE_BITMAP_HASH_CACHE; 102 else 103 opts.flags &= ~MIDX_WRITE_BITMAP_HASH_CACHE; 104 } 105 106 if (!strcmp(var, "pack.writebitmaplookuptable")) { 107 if (git_config_bool(var, value)) 108 opts.flags |= MIDX_WRITE_BITMAP_LOOKUP_TABLE; 109 else 110 opts.flags &= ~MIDX_WRITE_BITMAP_LOOKUP_TABLE; 111 } 112 113 /* 114 * We should never make a fall-back call to 'git_default_config', since 115 * this was already called in 'cmd_multi_pack_index()'. 116 */ 117 return 0; 118} 119 120static void read_packs_from_stdin(struct string_list *to) 121{ 122 struct strbuf buf = STRBUF_INIT; 123 while (strbuf_getline(&buf, stdin) != EOF) 124 string_list_append(to, buf.buf); 125 string_list_sort(to); 126 127 strbuf_release(&buf); 128} 129 130static int cmd_multi_pack_index_write(int argc, const char **argv, 131 const char *prefix, 132 struct repository *repo) 133{ 134 struct option *options; 135 static struct option builtin_multi_pack_index_write_options[] = { 136 OPT_STRING(0, "preferred-pack", &opts.preferred_pack, 137 N_("preferred-pack"), 138 N_("pack for reuse when computing a multi-pack bitmap")), 139 OPT_BIT(0, "bitmap", &opts.flags, N_("write multi-pack bitmap"), 140 MIDX_WRITE_BITMAP | MIDX_WRITE_REV_INDEX), 141 OPT_BIT(0, "progress", &opts.flags, 142 N_("force progress reporting"), MIDX_PROGRESS), 143 OPT_BIT(0, "incremental", &opts.flags, 144 N_("write a new incremental MIDX"), MIDX_WRITE_INCREMENTAL), 145 OPT_BOOL(0, "stdin-packs", &opts.stdin_packs, 146 N_("write multi-pack index containing only given indexes")), 147 OPT_FILENAME(0, "refs-snapshot", &opts.refs_snapshot, 148 N_("refs snapshot for selecting bitmap commits")), 149 OPT_END(), 150 }; 151 struct odb_source *source; 152 int ret; 153 154 opts.flags |= MIDX_WRITE_BITMAP_HASH_CACHE; 155 156 repo_config(the_repository, git_multi_pack_index_write_config, NULL); 157 158 options = add_common_options(builtin_multi_pack_index_write_options); 159 160 trace2_cmd_mode(argv[0]); 161 162 if (isatty(2)) 163 opts.flags |= MIDX_PROGRESS; 164 argc = parse_options(argc, argv, prefix, 165 options, builtin_multi_pack_index_write_usage, 166 0); 167 if (argc) 168 usage_with_options(builtin_multi_pack_index_write_usage, 169 options); 170 source = handle_object_dir_option(repo); 171 172 FREE_AND_NULL(options); 173 174 if (opts.stdin_packs) { 175 struct string_list packs = STRING_LIST_INIT_DUP; 176 177 read_packs_from_stdin(&packs); 178 179 ret = write_midx_file_only(source, &packs, 180 opts.preferred_pack, 181 opts.refs_snapshot, opts.flags); 182 183 string_list_clear(&packs, 0); 184 free(opts.refs_snapshot); 185 186 return ret; 187 188 } 189 190 ret = write_midx_file(source, opts.preferred_pack, 191 opts.refs_snapshot, opts.flags); 192 193 free(opts.refs_snapshot); 194 return ret; 195} 196 197static int cmd_multi_pack_index_verify(int argc, const char **argv, 198 const char *prefix, 199 struct repository *repo UNUSED) 200{ 201 struct option *options; 202 static struct option builtin_multi_pack_index_verify_options[] = { 203 OPT_BIT(0, "progress", &opts.flags, 204 N_("force progress reporting"), MIDX_PROGRESS), 205 OPT_END(), 206 }; 207 struct odb_source *source; 208 209 options = add_common_options(builtin_multi_pack_index_verify_options); 210 211 trace2_cmd_mode(argv[0]); 212 213 if (isatty(2)) 214 opts.flags |= MIDX_PROGRESS; 215 argc = parse_options(argc, argv, prefix, 216 options, builtin_multi_pack_index_verify_usage, 217 0); 218 if (argc) 219 usage_with_options(builtin_multi_pack_index_verify_usage, 220 options); 221 source = handle_object_dir_option(the_repository); 222 223 FREE_AND_NULL(options); 224 225 return verify_midx_file(source, opts.flags); 226} 227 228static int cmd_multi_pack_index_expire(int argc, const char **argv, 229 const char *prefix, 230 struct repository *repo UNUSED) 231{ 232 struct option *options; 233 static struct option builtin_multi_pack_index_expire_options[] = { 234 OPT_BIT(0, "progress", &opts.flags, 235 N_("force progress reporting"), MIDX_PROGRESS), 236 OPT_END(), 237 }; 238 struct odb_source *source; 239 240 options = add_common_options(builtin_multi_pack_index_expire_options); 241 242 trace2_cmd_mode(argv[0]); 243 244 if (isatty(2)) 245 opts.flags |= MIDX_PROGRESS; 246 argc = parse_options(argc, argv, prefix, 247 options, builtin_multi_pack_index_expire_usage, 248 0); 249 if (argc) 250 usage_with_options(builtin_multi_pack_index_expire_usage, 251 options); 252 source = handle_object_dir_option(the_repository); 253 254 FREE_AND_NULL(options); 255 256 return expire_midx_packs(source, opts.flags); 257} 258 259static int cmd_multi_pack_index_repack(int argc, const char **argv, 260 const char *prefix, 261 struct repository *repo UNUSED) 262{ 263 struct option *options; 264 static struct option builtin_multi_pack_index_repack_options[] = { 265 OPT_UNSIGNED(0, "batch-size", &opts.batch_size, 266 N_("during repack, collect pack-files of smaller size into a batch that is larger than this size")), 267 OPT_BIT(0, "progress", &opts.flags, 268 N_("force progress reporting"), MIDX_PROGRESS), 269 OPT_END(), 270 }; 271 struct odb_source *source; 272 273 options = add_common_options(builtin_multi_pack_index_repack_options); 274 275 trace2_cmd_mode(argv[0]); 276 277 if (isatty(2)) 278 opts.flags |= MIDX_PROGRESS; 279 argc = parse_options(argc, argv, prefix, 280 options, 281 builtin_multi_pack_index_repack_usage, 282 0); 283 if (argc) 284 usage_with_options(builtin_multi_pack_index_repack_usage, 285 options); 286 source = handle_object_dir_option(the_repository); 287 288 FREE_AND_NULL(options); 289 290 return midx_repack(source, (size_t)opts.batch_size, opts.flags); 291} 292 293int cmd_multi_pack_index(int argc, 294 const char **argv, 295 const char *prefix, 296 struct repository *repo) 297{ 298 int res; 299 parse_opt_subcommand_fn *fn = NULL; 300 struct option builtin_multi_pack_index_options[] = { 301 OPT_SUBCOMMAND("repack", &fn, cmd_multi_pack_index_repack), 302 OPT_SUBCOMMAND("write", &fn, cmd_multi_pack_index_write), 303 OPT_SUBCOMMAND("verify", &fn, cmd_multi_pack_index_verify), 304 OPT_SUBCOMMAND("expire", &fn, cmd_multi_pack_index_expire), 305 OPT_END(), 306 }; 307 struct option *options = parse_options_concat(builtin_multi_pack_index_options, common_opts); 308 309 disable_replace_refs(); 310 311 repo_config(the_repository, git_default_config, NULL); 312 313 if (the_repository && 314 the_repository->objects && 315 the_repository->objects->sources) 316 opts.object_dir = xstrdup(the_repository->objects->sources->path); 317 318 argc = parse_options(argc, argv, prefix, options, 319 builtin_multi_pack_index_usage, 0); 320 FREE_AND_NULL(options); 321 322 res = fn(argc, argv, prefix, repo); 323 324 free(opts.object_dir); 325 return res; 326}