Skip to content

Commit 58a8c38

Browse files
committed
Merge branch 'tb/combine-cruft-below-size'
"git repack" learned "--combine-cruft-below-size" option that controls how cruft-packs are combined. * tb/combine-cruft-below-size: repack: begin combining cruft packs with `--combine-cruft-below-size` repack: avoid combining cruft packs with `--max-cruft-size` t/t7704-repack-cruft.sh: consolidate `write_blob()` t/t7704-repack-cruft.sh: clarify wording in --max-cruft-size tests t/t5329-pack-objects-cruft.sh: evict 'repack'-related tests
2 parents 6a9e1c3 + 484d7ad commit 58a8c38

File tree

4 files changed

+355
-323
lines changed

4 files changed

+355
-323
lines changed

Documentation/git-repack.adoc

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -77,15 +77,18 @@ to the new separate pack will be written.
7777
Only useful with `--cruft -d`.
7878

7979
--max-cruft-size=<n>::
80-
Repack cruft objects into packs as large as `<n>` bytes before
81-
creating new packs. As long as there are enough cruft packs
82-
smaller than `<n>`, repacking will cause a new cruft pack to
83-
be created containing objects from any combined cruft packs,
84-
along with any new unreachable objects. Cruft packs larger than
85-
`<n>` will not be modified. When the new cruft pack is larger
86-
than `<n>` bytes, it will be split into multiple packs, all of
87-
which are guaranteed to be at most `<n>` bytes in size. Only
88-
useful with `--cruft -d`.
80+
Overrides `--max-pack-size` for cruft packs. Inherits the value of
81+
`--max-pack-size` (if any) by default. See the documentation for
82+
`--max-pack-size` for more details.
83+
84+
--combine-cruft-below-size=<n>::
85+
When generating cruft packs without pruning, only repack
86+
existing cruft packs whose size is strictly less than `<n>`,
87+
where `<n>` represents a number of bytes, which can optionally
88+
be suffixed with "k", "m", or "g". Cruft packs whose size is
89+
greater than or equal to `<n>` are left as-is and not repacked.
90+
Useful when you want to avoid repacking large cruft pack(s) in
91+
repositories that have many and/or large unreachable objects.
8992

9093
--expire-to=<dir>::
9194
Write a cruft pack containing pruned objects (if any) to the

builtin/repack.c

Lines changed: 21 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,29 +1022,13 @@ static int write_filtered_pack(const struct pack_objects_args *args,
10221022
return finish_pack_objects_cmd(&cmd, names, local);
10231023
}
10241024

1025-
static int existing_cruft_pack_cmp(const void *va, const void *vb)
1025+
static void combine_small_cruft_packs(FILE *in, size_t combine_cruft_below_size,
1026+
struct existing_packs *existing)
10261027
{
1027-
struct packed_git *a = *(struct packed_git **)va;
1028-
struct packed_git *b = *(struct packed_git **)vb;
1029-
1030-
if (a->pack_size < b->pack_size)
1031-
return -1;
1032-
if (a->pack_size > b->pack_size)
1033-
return 1;
1034-
return 0;
1035-
}
1036-
1037-
static void collapse_small_cruft_packs(FILE *in, size_t max_size,
1038-
struct existing_packs *existing)
1039-
{
1040-
struct packed_git **existing_cruft, *p;
1028+
struct packed_git *p;
10411029
struct strbuf buf = STRBUF_INIT;
1042-
size_t total_size = 0;
1043-
size_t existing_cruft_nr = 0;
10441030
size_t i;
10451031

1046-
ALLOC_ARRAY(existing_cruft, existing->cruft_packs.nr);
1047-
10481032
for (p = get_all_packs(the_repository); p; p = p->next) {
10491033
if (!(p->is_cruft && p->pack_local))
10501034
continue;
@@ -1056,24 +1040,7 @@ static void collapse_small_cruft_packs(FILE *in, size_t max_size,
10561040
if (!string_list_has_string(&existing->cruft_packs, buf.buf))
10571041
continue;
10581042

1059-
if (existing_cruft_nr >= existing->cruft_packs.nr)
1060-
BUG("too many cruft packs (found %"PRIuMAX", but knew "
1061-
"of %"PRIuMAX")",
1062-
(uintmax_t)existing_cruft_nr + 1,
1063-
(uintmax_t)existing->cruft_packs.nr);
1064-
existing_cruft[existing_cruft_nr++] = p;
1065-
}
1066-
1067-
QSORT(existing_cruft, existing_cruft_nr, existing_cruft_pack_cmp);
1068-
1069-
for (i = 0; i < existing_cruft_nr; i++) {
1070-
size_t proposed;
1071-
1072-
p = existing_cruft[i];
1073-
proposed = st_add(total_size, p->pack_size);
1074-
1075-
if (proposed <= max_size) {
1076-
total_size = proposed;
1043+
if (p->pack_size < combine_cruft_below_size) {
10771044
fprintf(in, "-%s\n", pack_basename(p));
10781045
} else {
10791046
retain_cruft_pack(existing, p);
@@ -1086,13 +1053,13 @@ static void collapse_small_cruft_packs(FILE *in, size_t max_size,
10861053
existing->non_kept_packs.items[i].string);
10871054

10881055
strbuf_release(&buf);
1089-
free(existing_cruft);
10901056
}
10911057

10921058
static int write_cruft_pack(const struct pack_objects_args *args,
10931059
const char *destination,
10941060
const char *pack_prefix,
10951061
const char *cruft_expiration,
1062+
unsigned long combine_cruft_below_size,
10961063
struct string_list *names,
10971064
struct existing_packs *existing)
10981065
{
@@ -1135,8 +1102,9 @@ static int write_cruft_pack(const struct pack_objects_args *args,
11351102
in = xfdopen(cmd.in, "w");
11361103
for_each_string_list_item(item, names)
11371104
fprintf(in, "%s-%s.pack\n", pack_prefix, item->string);
1138-
if (args->max_pack_size && !cruft_expiration) {
1139-
collapse_small_cruft_packs(in, args->max_pack_size, existing);
1105+
if (combine_cruft_below_size && !cruft_expiration) {
1106+
combine_small_cruft_packs(in, combine_cruft_below_size,
1107+
existing);
11401108
} else {
11411109
for_each_string_list_item(item, &existing->non_kept_packs)
11421110
fprintf(in, "-%s.pack\n", item->string);
@@ -1190,6 +1158,7 @@ int cmd_repack(int argc,
11901158
const char *opt_window_memory = NULL;
11911159
const char *opt_depth = NULL;
11921160
const char *opt_threads = NULL;
1161+
unsigned long combine_cruft_below_size = 0ul;
11931162

11941163
struct option builtin_repack_options[] = {
11951164
OPT_BIT('a', NULL, &pack_everything,
@@ -1202,6 +1171,9 @@ int cmd_repack(int argc,
12021171
PACK_CRUFT),
12031172
OPT_STRING(0, "cruft-expiration", &cruft_expiration, N_("approxidate"),
12041173
N_("with --cruft, expire objects older than this")),
1174+
OPT_MAGNITUDE(0, "combine-cruft-below-size",
1175+
&combine_cruft_below_size,
1176+
N_("with --cruft, only repack cruft packs smaller than this")),
12051177
OPT_MAGNITUDE(0, "max-cruft-size", &cruft_po_args.max_pack_size,
12061178
N_("with --cruft, limit the size of new cruft packs")),
12071179
OPT_BOOL('d', NULL, &delete_redundant,
@@ -1445,7 +1417,8 @@ int cmd_repack(int argc,
14451417
cruft_po_args.quiet = po_args.quiet;
14461418

14471419
ret = write_cruft_pack(&cruft_po_args, packtmp, pack_prefix,
1448-
cruft_expiration, &names,
1420+
cruft_expiration,
1421+
combine_cruft_below_size, &names,
14491422
&existing);
14501423
if (ret)
14511424
goto cleanup;
@@ -1472,10 +1445,17 @@ int cmd_repack(int argc,
14721445
* generate an empty pack (since every object not in the
14731446
* cruft pack generated above will have an mtime older
14741447
* than the expiration).
1448+
*
1449+
* Pretend we don't have a `--combine-cruft-below-size`
1450+
* argument, since we're not selectively combining
1451+
* anything based on size to generate the limbo cruft
1452+
* pack, but rather removing all cruft packs from the
1453+
* main repository regardless of size.
14751454
*/
14761455
ret = write_cruft_pack(&cruft_po_args, expire_to,
14771456
pack_prefix,
14781457
NULL,
1458+
0ul,
14791459
&names,
14801460
&existing);
14811461
if (ret)

0 commit comments

Comments
 (0)