434
geometry->split = 0;
435
}
436
437
+static void midx_included_packs(struct string_list *include,
438
+ struct string_list *existing_nonkept_packs,
439
+ struct string_list *existing_kept_packs,
440
+ struct string_list *names,
441
+ struct pack_geometry *geometry)
442
+{
443
+ struct string_list_item *item;
444
+
445
+ for_each_string_list_item(item, existing_kept_packs)
446
+ string_list_insert(include, xstrfmt("%s.idx", item->string));
447
+ for_each_string_list_item(item, names)
448
+ string_list_insert(include, xstrfmt("pack-%s.idx", item->string));
449
+ if (geometry) {
450
+ struct strbuf buf = STRBUF_INIT;
451
+ uint32_t i;
452
+ for (i = geometry->split; i < geometry->pack_nr; i++) {
453
+ struct packed_git *p = geometry->pack[i];
454
+
455
+ strbuf_addstr(&buf, pack_basename(p));
456
+ strbuf_strip_suffix(&buf, ".pack");
457
+ strbuf_addstr(&buf, ".idx");
458
+
459
+ string_list_insert(include, strbuf_detach(&buf, NULL));
460
+ }
461
+ } else {
462
+ for_each_string_list_item(item, existing_nonkept_packs) {
463
+ if (item->util)
464
+ continue;
465
+ string_list_insert(include, xstrfmt("%s.idx", item->string));
466
+ }
467
+ }
468
+}
469
+
470
+static int write_midx_included_packs(struct string_list *include,
471
+ int show_progress, int write_bitmaps)
472
+{
473
+ struct child_process cmd = CHILD_PROCESS_INIT;
474
+ struct string_list_item *item;
475
+ FILE *in;
476
+ int ret;
477
+
478
+ if (!include->nr)
479
+ return 0;
480
+
481
+ cmd.in = -1;
482
+ cmd.git_cmd = 1;
483
+
484
+ strvec_push(&cmd.args, "multi-pack-index");
485
+ strvec_pushl(&cmd.args, "write", "--stdin-packs", NULL);
486
+
487
+ if (show_progress)
488
+ strvec_push(&cmd.args, "--progress");
489
+ else
490
+ strvec_push(&cmd.args, "--no-progress");
491
+
492
+ if (write_bitmaps)
493
+ strvec_push(&cmd.args, "--bitmap");
494
+
495
+ ret = start_command(&cmd);
496
+ if (ret)
497
+ return ret;
498
+
499
+ in = xfdopen(cmd.in, "w");
500
+ for_each_string_list_item(item, include)
501
+ fprintf(in, "%s\n", item->string);
502
+ fclose(in);
503
+
504
+ return finish_command(&cmd);
505
+}
506
+
507
int cmd_repack(int argc, const char **argv, const char *prefix)
508
{
509
struct child_process cmd = CHILD_PROCESS_INIT;
527
int no_update_server_info = 0;
528
struct pack_objects_args po_args = {NULL};
529
int geometric_factor = 0;
530
+ int write_midx = 0;
531
532
struct option builtin_repack_options[] = {
533
OPT_BIT('a', NULL, &pack_everything,
570
N_("do not repack this pack")),
571
OPT_INTEGER('g', "geometric", &geometric_factor,
572
N_("find a geometric progression with factor <N>")),
573
+ OPT_BOOL('m', "write-midx", &write_midx,
574
+ N_("write a multi-pack index of the resulting packs")),
575
OPT_END()
576
};
577
588
die(_("--keep-unreachable and -A are incompatible"));
589
590
if (write_bitmaps < 0) {
518
- if (!(pack_everything & ALL_INTO_ONE) ||
519
- !is_bare_repository())
591
+ if (!write_midx &&
592
+ (!(pack_everything & ALL_INTO_ONE) || !is_bare_repository()))
593
write_bitmaps = 0;
594
} else if (write_bitmaps &&
595
git_env_bool(GIT_TEST_MULTI_PACK_INDEX, 0) &&
599
if (pack_kept_objects < 0)
600
pack_kept_objects = write_bitmaps > 0;
601
529
- if (write_bitmaps && !(pack_everything & ALL_INTO_ONE))
602
+ if (write_bitmaps && !(pack_everything & ALL_INTO_ONE) && !write_midx)
603
die(_(incremental_bitmap_conflict_error));
604
605
if (geometric_factor) {
641
}
642
if (has_promisor_remote())
643
strvec_push(&cmd.args, "--exclude-promisor-objects");
571
- if (write_bitmaps > 0)
572
- strvec_push(&cmd.args, "--write-bitmap-index");
573
- else if (write_bitmaps < 0)
574
- strvec_push(&cmd.args, "--write-bitmap-index-quiet");
644
+ if (!write_midx) {
645
+ if (write_bitmaps > 0)
646
+ strvec_push(&cmd.args, "--write-bitmap-index");
647
+ else if (write_bitmaps < 0)
648
+ strvec_push(&cmd.args, "--write-bitmap-index-quiet");
649
+ }
650
if (use_delta_islands)
651
strvec_push(&cmd.args, "--delta-islands");
652
759
}
760
/* End of pack replacement. */
761
762
+ if (delete_redundant && pack_everything & ALL_INTO_ONE) {
763
+ const int hexsz = the_hash_algo->hexsz;
764
+ string_list_sort(&names);
765
+ for_each_string_list_item(item, &existing_nonkept_packs) {
766
+ char *sha1;
767
+ size_t len = strlen(item->string);
768
+ if (len < hexsz)
769
+ continue;
770
+ sha1 = item->string + len - hexsz;
771
+ /*
772
+ * Mark this pack for deletion, which ensures that this
773
+ * pack won't be included in a MIDX (if `--write-midx`
774
+ * was given) and that we will actually delete this pack
775
+ * (if `-d` was given).
776
+ */
777
+ item->util = (void*)(intptr_t)!string_list_has_string(&names, sha1);
778
+ }
779
+ }
780
+
781
+ if (write_midx) {
782
+ struct string_list include = STRING_LIST_INIT_NODUP;
783
+ midx_included_packs(&include, &existing_nonkept_packs,
784
+ &existing_kept_packs, &names, geometry);
785
+
786
+ ret = write_midx_included_packs(&include,
787
+ show_progress, write_bitmaps > 0);
788
+
789
+ string_list_clear(&include, 0);
790
+
791
+ if (ret)
792
+ return ret;
793
+ }
794
+
795
reprepare_packed_git(the_repository);
796
797
if (delete_redundant) {
798
int opts = 0;
691
- if (pack_everything & ALL_INTO_ONE) {
692
- const int hexsz = the_hash_algo->hexsz;
693
- string_list_sort(&names);
694
- for_each_string_list_item(item, &existing_nonkept_packs) {
695
- char *sha1;
696
- size_t len = strlen(item->string);
697
- if (len < hexsz)
698
- continue;
699
- sha1 = item->string + len - hexsz;
700
- if (!string_list_has_string(&names, sha1))
701
- remove_redundant_pack(packdir, item->string);
702
- }
799
+ for_each_string_list_item(item, &existing_nonkept_packs) {
800
+ if (!item->util)
801
+ continue;
802
+ remove_redundant_pack(packdir, item->string);
803
}
804
805
if (geometry) {