builtin/repack.c: keep track of existing packs unconditionally

In order to be able to write a multi-pack index during repacking, `git repack` must keep track of which packs it wants to write into the MIDX. This set is the union of existing packs which will not be deleted, new pack(s) generated as a result of the repack, and .keep packs. Prior to this patch, `git repack` populated the list of existing packs only when repacking all-into-one (i.e., with `-A` or `-a`), but we will soon need to know this list when repacking when writing a MIDX without a-i-o. Populate the list of existing packs unconditionally, and guard removing packs from that list only when repacking a-i-o. Additionally, keep track of filenames of kept packs separately, since this, too, will be used in an upcoming patch. Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Taylor Blau committed Sep 28, 2021 at 21:55 UTC 90f838bc368d0a3495fb4164dd76e505bf761b29
1 file changed +31 -25
builtin/repack.c
+31 -25
@@ -94,12 +94,14 @@ static void remove_pack_on_signal(int signo)
94 }
95
96 /*
97 - * Adds all packs hex strings to the fname list, which do not
98 - * have a corresponding .keep file. These packs are not to
99 - * be kept if we are going to pack everything into one file.
97 + * Adds all packs hex strings to either fname_list or fname_kept_list
98 + * based on whether each pack has a corresponding .keep file or not.
99 + * Packs without a .keep file are not to be kept if we are going to
100 + * pack everything into one file.
101 */
101 -static void get_non_kept_pack_filenames(struct string_list *fname_list,
102 - const struct string_list *extra_keep)
102 +static void collect_pack_filenames(struct string_list *fname_list,
103 + struct string_list *fname_kept_list,
104 + const struct string_list *extra_keep)
105 {
106 DIR *dir;
107 struct dirent *e;
@@ -112,21 +114,20 @@ static void get_non_kept_pack_filenames(struct string_list *fname_list,
114 size_t len;
115 int i;
116
117 + if (!strip_suffix(e->d_name, ".pack", &len))
118 + continue;
119 +
120 for (i = 0; i < extra_keep->nr; i++)
121 if (!fspathcmp(e->d_name, extra_keep->items[i].string))
122 break;
118 - if (extra_keep->nr > 0 && i < extra_keep->nr)
119 - continue;
120 -
121 - if (!strip_suffix(e->d_name, ".pack", &len))
122 - continue;
123
124 fname = xmemdupz(e->d_name, len);
125
126 - if (!file_exists(mkpath("%s/%s.keep", packdir, fname)))
127 - string_list_append_nodup(fname_list, fname);
126 + if ((extra_keep->nr > 0 && i < extra_keep->nr) ||
127 + (file_exists(mkpath("%s/%s.keep", packdir, fname))))
128 + string_list_append_nodup(fname_kept_list, fname);
129 else
129 - free(fname);
130 + string_list_append_nodup(fname_list, fname);
131 }
132 closedir(dir);
133 }
@@ -440,6 +441,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
441 struct string_list names = STRING_LIST_INIT_DUP;
442 struct string_list rollback = STRING_LIST_INIT_NODUP;
443 struct string_list existing_packs = STRING_LIST_INIT_DUP;
444 + struct string_list existing_kept_packs = STRING_LIST_INIT_DUP;
445 struct pack_geometry *geometry = NULL;
446 struct strbuf line = STRBUF_INIT;
447 int i, ext, ret;
@@ -572,9 +574,10 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
574 if (use_delta_islands)
575 strvec_push(&cmd.args, "--delta-islands");
576
575 - if (pack_everything & ALL_INTO_ONE) {
576 - get_non_kept_pack_filenames(&existing_packs, &keep_pack_list);
577 + collect_pack_filenames(&existing_packs, &existing_kept_packs,
578 + &keep_pack_list);
579
580 + if (pack_everything & ALL_INTO_ONE) {
581 repack_promisor_objects(&po_args, &names);
582
583 if (existing_packs.nr && delete_redundant) {
@@ -683,17 +686,19 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
686 reprepare_packed_git(the_repository);
687
688 if (delete_redundant) {
686 - const int hexsz = the_hash_algo->hexsz;
689 int opts = 0;
688 - string_list_sort(&names);
689 - for_each_string_list_item(item, &existing_packs) {
690 - char *sha1;
691 - size_t len = strlen(item->string);
692 - if (len < hexsz)
693 - continue;
694 - sha1 = item->string + len - hexsz;
695 - if (!string_list_has_string(&names, sha1))
696 - remove_redundant_pack(packdir, item->string);
690 + if (pack_everything & ALL_INTO_ONE) {
691 + const int hexsz = the_hash_algo->hexsz;
692 + string_list_sort(&names);
693 + for_each_string_list_item(item, &existing_packs) {
694 + char *sha1;
695 + size_t len = strlen(item->string);
696 + if (len < hexsz)
697 + continue;
698 + sha1 = item->string + len - hexsz;
699 + if (!string_list_has_string(&names, sha1))
700 + remove_redundant_pack(packdir, item->string);
701 + }
702 }
703
704 if (geometry) {
@@ -739,6 +744,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
744 string_list_clear(&names, 0);
745 string_list_clear(&rollback, 0);
746 string_list_clear(&existing_packs, 0);
747 + string_list_clear(&existing_kept_packs, 0);
748 clear_pack_geometry(geometry);
749 strbuf_release(&line);
750