]> git.ipfire.org Git - thirdparty/git.git/blame - builtin/repack.c
builtin/repack.c: only repack `.pack`s that exist
[thirdparty/git.git] / builtin / repack.c
CommitLineData
a1bbc6c0 1#include "builtin.h"
36bf1958 2#include "alloc.h"
b2141fc1 3#include "config.h"
a1bbc6c0 4#include "dir.h"
32a8f510 5#include "environment.h"
f394e093 6#include "gettext.h"
41771fa4 7#include "hex.h"
a1bbc6c0 8#include "parse-options.h"
c339932b 9#include "path.h"
a1bbc6c0 10#include "run-command.h"
623b80be 11#include "server-info.h"
a1bbc6c0
SB
12#include "sigchain.h"
13#include "strbuf.h"
14#include "string-list.h"
dbbcd44f 15#include "strvec.h"
525e18c0 16#include "midx.h"
5d19e813 17#include "packfile.h"
9460fd48 18#include "prune-packed.h"
a034e910 19#include "object-store-ll.h"
b14ed5ad 20#include "promisor-remote.h"
120ad2b0 21#include "shallow.h"
33add2ad 22#include "pack.h"
324efc90
TB
23#include "pack-bitmap.h"
24#include "refs.h"
a1bbc6c0 25
f9825d1c
TB
26#define ALL_INTO_ONE 1
27#define LOOSEN_UNREACHABLE 2
28#define PACK_CRUFT 4
29
72263ffc 30#define DELETE_PACK 1
ddee3703 31#define CRUFT_PACK 2
72263ffc 32
f9825d1c 33static int pack_everything;
a1bbc6c0 34static int delta_base_offset = 1;
ee34a2be 35static int pack_kept_objects = -1;
36eba032 36static int write_bitmaps = -1;
16d75fa4 37static int use_delta_islands;
a2565c48 38static int run_update_server_info = 1;
a643157d 39static char *packdir, *packtmp_name, *packtmp;
a1bbc6c0
SB
40
41static const char *const git_repack_usage[] = {
9c9b4f2f 42 N_("git repack [<options>]"),
a1bbc6c0
SB
43 NULL
44};
45
1c409a70
DT
46static const char incremental_bitmap_conflict_error[] = N_(
47"Incremental repacks are incompatible with bitmap indexes. Use\n"
b4eda05d 48"--no-write-bitmap-index or disable the pack.writeBitmaps configuration."
1c409a70
DT
49);
50
4571324b
TB
51struct pack_objects_args {
52 const char *window;
53 const char *window_memory;
54 const char *depth;
55 const char *threads;
56 const char *max_pack_size;
57 int no_reuse_delta;
58 int no_reuse_object;
59 int quiet;
60 int local;
61};
1c409a70 62
a4e7e317
GC
63static int repack_config(const char *var, const char *value,
64 const struct config_context *ctx, void *cb)
a1bbc6c0 65{
4571324b 66 struct pack_objects_args *cruft_po_args = cb;
a1bbc6c0
SB
67 if (!strcmp(var, "repack.usedeltabaseoffset")) {
68 delta_base_offset = git_config_bool(var, value);
69 return 0;
70 }
ee34a2be
JK
71 if (!strcmp(var, "repack.packkeptobjects")) {
72 pack_kept_objects = git_config_bool(var, value);
73 return 0;
74 }
71d76cb4
JK
75 if (!strcmp(var, "repack.writebitmaps") ||
76 !strcmp(var, "pack.writebitmaps")) {
d078d85b 77 write_bitmaps = git_config_bool(var, value);
3198b89f
JK
78 return 0;
79 }
16d75fa4
JK
80 if (!strcmp(var, "repack.usedeltaislands")) {
81 use_delta_islands = git_config_bool(var, value);
82 return 0;
83 }
a2565c48
PS
84 if (strcmp(var, "repack.updateserverinfo") == 0) {
85 run_update_server_info = git_config_bool(var, value);
86 return 0;
87 }
4571324b
TB
88 if (!strcmp(var, "repack.cruftwindow"))
89 return git_config_string(&cruft_po_args->window, var, value);
90 if (!strcmp(var, "repack.cruftwindowmemory"))
91 return git_config_string(&cruft_po_args->window_memory, var, value);
92 if (!strcmp(var, "repack.cruftdepth"))
93 return git_config_string(&cruft_po_args->depth, var, value);
94 if (!strcmp(var, "repack.cruftthreads"))
95 return git_config_string(&cruft_po_args->threads, var, value);
a4e7e317 96 return git_default_config(var, value, ctx, cb);
a1bbc6c0
SB
97}
98
a1bbc6c0 99/*
73320e49
TB
100 * Adds all packs hex strings (pack-$HASH) to either fname_nonkept_list
101 * or fname_kept_list based on whether each pack has a corresponding
a169166d
TB
102 * .keep file or not. Packs without a .keep file are not to be kept
103 * if we are going to pack everything into one file.
a1bbc6c0 104 */
a169166d 105static void collect_pack_filenames(struct string_list *fname_nonkept_list,
90f838bc
TB
106 struct string_list *fname_kept_list,
107 const struct string_list *extra_keep)
a1bbc6c0
SB
108{
109 DIR *dir;
110 struct dirent *e;
111 char *fname;
73320e49 112 struct strbuf buf = STRBUF_INIT;
a1bbc6c0
SB
113
114 if (!(dir = opendir(packdir)))
115 return;
116
117 while ((e = readdir(dir)) != NULL) {
26936bfd 118 size_t len;
ed7e5fc3
NTND
119 int i;
120
73320e49 121 if (!strip_suffix(e->d_name, ".idx", &len))
90f838bc
TB
122 continue;
123
73320e49
TB
124 strbuf_reset(&buf);
125 strbuf_add(&buf, e->d_name, len);
126 strbuf_addstr(&buf, ".pack");
127
0af06727
DS
128 if (!file_exists(mkpath("%s/%s", packdir, buf.buf)))
129 continue;
130
ed7e5fc3 131 for (i = 0; i < extra_keep->nr; i++)
73320e49 132 if (!fspathcmp(buf.buf, extra_keep->items[i].string))
ed7e5fc3 133 break;
a1bbc6c0 134
a1bbc6c0
SB
135 fname = xmemdupz(e->d_name, len);
136
90f838bc 137 if ((extra_keep->nr > 0 && i < extra_keep->nr) ||
ddee3703 138 (file_exists(mkpath("%s/%s.keep", packdir, fname)))) {
90f838bc 139 string_list_append_nodup(fname_kept_list, fname);
ddee3703
TB
140 } else {
141 struct string_list_item *item;
142 item = string_list_append_nodup(fname_nonkept_list,
143 fname);
144 if (file_exists(mkpath("%s/%s.mtimes", packdir, fname)))
145 item->util = (void*)(uintptr_t)CRUFT_PACK;
146 }
a1bbc6c0
SB
147 }
148 closedir(dir);
73320e49 149 strbuf_release(&buf);
4b5a808b
VD
150
151 string_list_sort(fname_kept_list);
a1bbc6c0
SB
152}
153
154static void remove_redundant_pack(const char *dir_name, const char *base_name)
155{
a1bbc6c0 156 struct strbuf buf = STRBUF_INIT;
59552fb3 157 struct multi_pack_index *m = get_local_multi_pack_index(the_repository);
e08f7bb0
TB
158 strbuf_addf(&buf, "%s.pack", base_name);
159 if (m && midx_contains_pack(m, buf.buf))
160 clear_midx_file(the_repository);
161 strbuf_insertf(&buf, 0, "%s/", dir_name);
8434e85d 162 unlink_pack_path(buf.buf, 1);
a1bbc6c0
SB
163 strbuf_release(&buf);
164}
165
2b958e79 166static void prepare_pack_objects(struct child_process *cmd,
4e7b65ba
TB
167 const struct pack_objects_args *args,
168 const char *out)
2b958e79 169{
22f9b7f3 170 strvec_push(&cmd->args, "pack-objects");
2b958e79 171 if (args->window)
22f9b7f3 172 strvec_pushf(&cmd->args, "--window=%s", args->window);
2b958e79 173 if (args->window_memory)
22f9b7f3 174 strvec_pushf(&cmd->args, "--window-memory=%s", args->window_memory);
2b958e79 175 if (args->depth)
22f9b7f3 176 strvec_pushf(&cmd->args, "--depth=%s", args->depth);
2b958e79 177 if (args->threads)
22f9b7f3 178 strvec_pushf(&cmd->args, "--threads=%s", args->threads);
2b958e79 179 if (args->max_pack_size)
22f9b7f3 180 strvec_pushf(&cmd->args, "--max-pack-size=%s", args->max_pack_size);
2b958e79 181 if (args->no_reuse_delta)
22f9b7f3 182 strvec_pushf(&cmd->args, "--no-reuse-delta");
2b958e79 183 if (args->no_reuse_object)
22f9b7f3 184 strvec_pushf(&cmd->args, "--no-reuse-object");
2b958e79 185 if (args->local)
22f9b7f3 186 strvec_push(&cmd->args, "--local");
2b958e79 187 if (args->quiet)
22f9b7f3 188 strvec_push(&cmd->args, "--quiet");
2b958e79 189 if (delta_base_offset)
22f9b7f3 190 strvec_push(&cmd->args, "--delta-base-offset");
4e7b65ba 191 strvec_push(&cmd->args, out);
2b958e79
JT
192 cmd->git_cmd = 1;
193 cmd->out = -1;
194}
195
5d19e813
JT
196/*
197 * Write oid to the given struct child_process's stdin, starting it first if
198 * necessary.
199 */
be252d33
JK
200static int write_oid(const struct object_id *oid,
201 struct packed_git *pack UNUSED,
202 uint32_t pos UNUSED, void *data)
5d19e813
JT
203{
204 struct child_process *cmd = data;
205
206 if (cmd->in == -1) {
207 if (start_command(cmd))
c83d950e 208 die(_("could not start pack-objects to repack promisor objects"));
5d19e813
JT
209 }
210
dd336a55 211 xwrite(cmd->in, oid_to_hex(oid), the_hash_algo->hexsz);
5d19e813
JT
212 xwrite(cmd->in, "\n", 1);
213 return 0;
214}
215
63f4d5cf
JK
216static struct {
217 const char *name;
218 unsigned optional:1;
219} exts[] = {
220 {".pack"},
2f4ba2a8 221 {".rev", 1},
94cd775a 222 {".mtimes", 1},
63f4d5cf
JK
223 {".bitmap", 1},
224 {".promisor", 1},
4e58cedd 225 {".idx"},
63f4d5cf
JK
226};
227
d3d9c519 228struct generated_pack_data {
9cf10d87 229 struct tempfile *tempfiles[ARRAY_SIZE(exts)];
d3d9c519
JK
230};
231
232static struct generated_pack_data *populate_pack_exts(const char *name)
704c4a5c
TB
233{
234 struct stat statbuf;
235 struct strbuf path = STRBUF_INIT;
d3d9c519 236 struct generated_pack_data *data = xcalloc(1, sizeof(*data));
704c4a5c
TB
237 int i;
238
239 for (i = 0; i < ARRAY_SIZE(exts); i++) {
240 strbuf_reset(&path);
241 strbuf_addf(&path, "%s-%s%s", packtmp, name, exts[i].name);
242
243 if (stat(path.buf, &statbuf))
244 continue;
245
9cf10d87 246 data->tempfiles[i] = register_tempfile(path.buf);
704c4a5c
TB
247 }
248
249 strbuf_release(&path);
d3d9c519 250 return data;
704c4a5c
TB
251}
252
5d19e813
JT
253static void repack_promisor_objects(const struct pack_objects_args *args,
254 struct string_list *names)
255{
256 struct child_process cmd = CHILD_PROCESS_INIT;
257 FILE *out;
258 struct strbuf line = STRBUF_INIT;
259
4e7b65ba 260 prepare_pack_objects(&cmd, args, packtmp);
5d19e813
JT
261 cmd.in = -1;
262
263 /*
264 * NEEDSWORK: Giving pack-objects only the OIDs without any ordering
265 * hints may result in suboptimal deltas in the resulting pack. See if
266 * the OIDs can be sent with fake paths such that pack-objects can use a
267 * {type -> existing pack order} ordering when computing deltas instead
268 * of a {type -> size} ordering, which may produce better deltas.
269 */
270 for_each_packed_object(write_oid, &cmd,
271 FOR_EACH_OBJECT_PROMISOR_ONLY);
272
e6432e0f 273 if (cmd.in == -1) {
5d19e813 274 /* No packed objects; cmd was never started */
e6432e0f 275 child_process_clear(&cmd);
5d19e813 276 return;
e6432e0f 277 }
5d19e813
JT
278
279 close(cmd.in);
280
281 out = xfdopen(cmd.out, "r");
282 while (strbuf_getline_lf(&line, out) != EOF) {
704c4a5c 283 struct string_list_item *item;
5d19e813 284 char *promisor_name;
33add2ad 285
2f0c9e9a 286 if (line.len != the_hash_algo->hexsz)
3813a89f 287 die(_("repack: Expecting full hex object ID lines only from pack-objects."));
704c4a5c 288 item = string_list_append(names, line.buf);
5d19e813
JT
289
290 /*
291 * pack-objects creates the .pack and .idx files, but not the
292 * .promisor file. Create the .promisor file, which is empty.
5374a290
JT
293 *
294 * NEEDSWORK: fetch-pack sometimes generates non-empty
295 * .promisor files containing the ref names and associated
296 * hashes at the point of generation of the corresponding
297 * packfile, but this would not preserve their contents. Maybe
298 * concatenate the contents of all .promisor files instead of
299 * just creating a new empty file.
5d19e813
JT
300 */
301 promisor_name = mkpathdup("%s-%s.promisor", packtmp,
302 line.buf);
33add2ad 303 write_promisor_file(promisor_name, NULL, 0);
704c4a5c 304
d3d9c519 305 item->util = populate_pack_exts(item->string);
704c4a5c 306
5d19e813
JT
307 free(promisor_name);
308 }
309 fclose(out);
310 if (finish_command(&cmd))
c83d950e 311 die(_("could not finish pack-objects to repack promisor objects"));
5d19e813
JT
312}
313
0fabafd0
TB
314struct pack_geometry {
315 struct packed_git **pack;
316 uint32_t pack_nr, pack_alloc;
317 uint32_t split;
318};
319
320static uint32_t geometry_pack_weight(struct packed_git *p)
321{
322 if (open_pack_index(p))
323 die(_("cannot open index for %s"), p->pack_name);
324 return p->num_objects;
325}
326
327static int geometry_cmp(const void *va, const void *vb)
328{
329 uint32_t aw = geometry_pack_weight(*(struct packed_git **)va),
330 bw = geometry_pack_weight(*(struct packed_git **)vb);
331
332 if (aw < bw)
333 return -1;
334 if (aw > bw)
335 return 1;
336 return 0;
337}
338
4b5a808b 339static void init_pack_geometry(struct pack_geometry **geometry_p,
932c16c0
PS
340 struct string_list *existing_kept_packs,
341 const struct pack_objects_args *args)
0fabafd0
TB
342{
343 struct packed_git *p;
344 struct pack_geometry *geometry;
4b5a808b 345 struct strbuf buf = STRBUF_INIT;
0fabafd0
TB
346
347 *geometry_p = xcalloc(1, sizeof(struct pack_geometry));
348 geometry = *geometry_p;
349
350 for (p = get_all_packs(the_repository); p; p = p->next) {
932c16c0
PS
351 if (args->local && !p->pack_local)
352 /*
353 * When asked to only repack local packfiles we skip
354 * over any packfiles that are borrowed from alternate
355 * object directories.
356 */
357 continue;
358
4b5a808b
VD
359 if (!pack_kept_objects) {
360 /*
361 * Any pack that has its pack_keep bit set will appear
362 * in existing_kept_packs below, but this saves us from
363 * doing a more expensive check.
364 */
365 if (p->pack_keep)
366 continue;
367
368 /*
369 * The pack may be kept via the --keep-pack option;
370 * check 'existing_kept_packs' to determine whether to
371 * ignore it.
372 */
373 strbuf_reset(&buf);
374 strbuf_addstr(&buf, pack_basename(p));
375 strbuf_strip_suffix(&buf, ".pack");
376
377 if (string_list_has_string(existing_kept_packs, buf.buf))
378 continue;
379 }
f9825d1c
TB
380 if (p->is_cruft)
381 continue;
0fabafd0
TB
382
383 ALLOC_GROW(geometry->pack,
384 geometry->pack_nr + 1,
385 geometry->pack_alloc);
386
387 geometry->pack[geometry->pack_nr] = p;
388 geometry->pack_nr++;
389 }
390
391 QSORT(geometry->pack, geometry->pack_nr, geometry_cmp);
4b5a808b 392 strbuf_release(&buf);
0fabafd0
TB
393}
394
395static void split_pack_geometry(struct pack_geometry *geometry, int factor)
396{
397 uint32_t i;
398 uint32_t split;
399 off_t total_size = 0;
400
f25e33c1 401 if (!geometry->pack_nr) {
0fabafd0
TB
402 geometry->split = geometry->pack_nr;
403 return;
404 }
405
0fabafd0
TB
406 /*
407 * First, count the number of packs (in descending order of size) which
408 * already form a geometric progression.
409 */
410 for (i = geometry->pack_nr - 1; i > 0; i--) {
411 struct packed_git *ours = geometry->pack[i];
412 struct packed_git *prev = geometry->pack[i - 1];
2a159641
TB
413
414 if (unsigned_mult_overflows(factor, geometry_pack_weight(prev)))
415 die(_("pack %s too large to consider in geometric "
416 "progression"),
417 prev->pack_name);
418
13d746a3 419 if (geometry_pack_weight(ours) < factor * geometry_pack_weight(prev))
0fabafd0
TB
420 break;
421 }
422
13d746a3
TB
423 split = i;
424
0fabafd0
TB
425 if (split) {
426 /*
427 * Move the split one to the right, since the top element in the
428 * last-compared pair can't be in the progression. Only do this
429 * when we split in the middle of the array (otherwise if we got
430 * to the end, then the split is in the right place).
431 */
432 split++;
433 }
434
435 /*
436 * Then, anything to the left of 'split' must be in a new pack. But,
437 * creating that new pack may cause packs in the heavy half to no longer
438 * form a geometric progression.
439 *
440 * Compute an expected size of the new pack, and then determine how many
441 * packs in the heavy half need to be joined into it (if any) to restore
442 * the geometric progression.
443 */
2a159641
TB
444 for (i = 0; i < split; i++) {
445 struct packed_git *p = geometry->pack[i];
446
447 if (unsigned_add_overflows(total_size, geometry_pack_weight(p)))
448 die(_("pack %s too large to roll up"), p->pack_name);
449 total_size += geometry_pack_weight(p);
450 }
0fabafd0
TB
451 for (i = split; i < geometry->pack_nr; i++) {
452 struct packed_git *ours = geometry->pack[i];
2a159641
TB
453
454 if (unsigned_mult_overflows(factor, total_size))
455 die(_("pack %s too large to roll up"), ours->pack_name);
456
0fabafd0 457 if (geometry_pack_weight(ours) < factor * total_size) {
2a159641
TB
458 if (unsigned_add_overflows(total_size,
459 geometry_pack_weight(ours)))
460 die(_("pack %s too large to roll up"),
461 ours->pack_name);
462
0fabafd0
TB
463 split++;
464 total_size += geometry_pack_weight(ours);
465 } else
466 break;
467 }
468
469 geometry->split = split;
470}
471
3d74a233 472static struct packed_git *get_preferred_pack(struct pack_geometry *geometry)
6d08b9d4 473{
3d74a233
PS
474 uint32_t i;
475
6d08b9d4
TB
476 if (!geometry) {
477 /*
478 * No geometry means either an all-into-one repack (in which
479 * case there is only one pack left and it is the largest) or an
480 * incremental one.
481 *
482 * If repacking incrementally, then we could check the size of
483 * all packs to determine which should be preferred, but leave
484 * this for later.
485 */
486 return NULL;
487 }
488 if (geometry->split == geometry->pack_nr)
489 return NULL;
3d74a233
PS
490
491 /*
492 * The preferred pack is the largest pack above the split line. In
493 * other words, it is the largest pack that does not get rolled up in
494 * the geometric repack.
495 */
496 for (i = geometry->pack_nr; i > geometry->split; i--)
497 /*
498 * A pack that is not local would never be included in a
499 * multi-pack index. We thus skip over any non-local packs.
500 */
501 if (geometry->pack[i - 1]->pack_local)
502 return geometry->pack[i - 1];
503
504 return NULL;
6d08b9d4
TB
505}
506
0fabafd0
TB
507static void clear_pack_geometry(struct pack_geometry *geometry)
508{
509 if (!geometry)
510 return;
511
512 free(geometry->pack);
513 geometry->pack_nr = 0;
514 geometry->pack_alloc = 0;
515 geometry->split = 0;
516}
517
324efc90
TB
518struct midx_snapshot_ref_data {
519 struct tempfile *f;
520 struct oidset seen;
521 int preferred;
522};
523
5cf88fd8 524static int midx_snapshot_ref_one(const char *refname UNUSED,
324efc90 525 const struct object_id *oid,
5cf88fd8 526 int flag UNUSED, void *_data)
324efc90
TB
527{
528 struct midx_snapshot_ref_data *data = _data;
529 struct object_id peeled;
530
531 if (!peel_iterated_oid(oid, &peeled))
532 oid = &peeled;
533
534 if (oidset_insert(&data->seen, oid))
535 return 0; /* already seen */
536
537 if (oid_object_info(the_repository, oid, NULL) != OBJ_COMMIT)
538 return 0;
539
540 fprintf(data->f->fp, "%s%s\n", data->preferred ? "+" : "",
541 oid_to_hex(oid));
542
543 return 0;
544}
545
546static void midx_snapshot_refs(struct tempfile *f)
547{
548 struct midx_snapshot_ref_data data;
549 const struct string_list *preferred = bitmap_preferred_tips(the_repository);
550
551 data.f = f;
552 data.preferred = 0;
553 oidset_init(&data.seen, 0);
554
555 if (!fdopen_tempfile(f, "w"))
556 die(_("could not open tempfile %s for writing"),
557 get_tempfile_path(f));
558
559 if (preferred) {
560 struct string_list_item *item;
561
562 data.preferred = 1;
563 for_each_string_list_item(item, preferred)
564 for_each_ref_in(item->string, midx_snapshot_ref_one, &data);
565 data.preferred = 0;
566 }
567
568 for_each_ref(midx_snapshot_ref_one, &data);
569
570 if (close_tempfile_gently(f)) {
571 int save_errno = errno;
572 delete_tempfile(&f);
573 errno = save_errno;
574 die_errno(_("could not close refs snapshot tempfile"));
575 }
576
577 oidset_clear(&data.seen);
578}
579
1d89d88d
TB
580static void midx_included_packs(struct string_list *include,
581 struct string_list *existing_nonkept_packs,
582 struct string_list *existing_kept_packs,
583 struct string_list *names,
584 struct pack_geometry *geometry)
585{
586 struct string_list_item *item;
587
588 for_each_string_list_item(item, existing_kept_packs)
589 string_list_insert(include, xstrfmt("%s.idx", item->string));
590 for_each_string_list_item(item, names)
591 string_list_insert(include, xstrfmt("pack-%s.idx", item->string));
592 if (geometry) {
593 struct strbuf buf = STRBUF_INIT;
594 uint32_t i;
595 for (i = geometry->split; i < geometry->pack_nr; i++) {
596 struct packed_git *p = geometry->pack[i];
597
51861340
PS
598 /*
599 * The multi-pack index never refers to packfiles part
600 * of an alternate object database, so we skip these.
601 * While git-multi-pack-index(1) would silently ignore
602 * them anyway, this allows us to skip executing the
603 * command completely when we have only non-local
604 * packfiles.
605 */
606 if (!p->pack_local)
607 continue;
608
1d89d88d
TB
609 strbuf_addstr(&buf, pack_basename(p));
610 strbuf_strip_suffix(&buf, ".pack");
611 strbuf_addstr(&buf, ".idx");
612
613 string_list_insert(include, strbuf_detach(&buf, NULL));
614 }
ddee3703
TB
615
616 for_each_string_list_item(item, existing_nonkept_packs) {
617 if (!((uintptr_t)item->util & CRUFT_PACK)) {
618 /*
619 * no need to check DELETE_PACK, since we're not
620 * doing an ALL_INTO_ONE repack
621 */
622 continue;
623 }
624 string_list_insert(include, xstrfmt("%s.idx", item->string));
625 }
1d89d88d
TB
626 } else {
627 for_each_string_list_item(item, existing_nonkept_packs) {
72263ffc 628 if ((uintptr_t)item->util & DELETE_PACK)
1d89d88d
TB
629 continue;
630 string_list_insert(include, xstrfmt("%s.idx", item->string));
631 }
632 }
633}
634
635static int write_midx_included_packs(struct string_list *include,
6d08b9d4 636 struct pack_geometry *geometry,
324efc90 637 const char *refs_snapshot,
1d89d88d
TB
638 int show_progress, int write_bitmaps)
639{
640 struct child_process cmd = CHILD_PROCESS_INIT;
641 struct string_list_item *item;
3d74a233 642 struct packed_git *preferred = get_preferred_pack(geometry);
1d89d88d
TB
643 FILE *in;
644 int ret;
645
646 if (!include->nr)
647 return 0;
648
649 cmd.in = -1;
650 cmd.git_cmd = 1;
651
652 strvec_push(&cmd.args, "multi-pack-index");
653 strvec_pushl(&cmd.args, "write", "--stdin-packs", NULL);
654
655 if (show_progress)
656 strvec_push(&cmd.args, "--progress");
657 else
658 strvec_push(&cmd.args, "--no-progress");
659
660 if (write_bitmaps)
661 strvec_push(&cmd.args, "--bitmap");
662
3d74a233 663 if (preferred)
6d08b9d4 664 strvec_pushf(&cmd.args, "--preferred-pack=%s",
3d74a233 665 pack_basename(preferred));
6d08b9d4 666
324efc90
TB
667 if (refs_snapshot)
668 strvec_pushf(&cmd.args, "--refs-snapshot=%s", refs_snapshot);
669
1d89d88d
TB
670 ret = start_command(&cmd);
671 if (ret)
672 return ret;
673
674 in = xfdopen(cmd.in, "w");
675 for_each_string_list_item(item, include)
676 fprintf(in, "%s\n", item->string);
677 fclose(in);
678
679 return finish_command(&cmd);
680}
681
55d902cd
TB
682static void remove_redundant_bitmaps(struct string_list *include,
683 const char *packdir)
684{
685 struct strbuf path = STRBUF_INIT;
686 struct string_list_item *item;
687 size_t packdir_len;
688
689 strbuf_addstr(&path, packdir);
690 strbuf_addch(&path, '/');
691 packdir_len = path.len;
692
693 /*
694 * Remove any pack bitmaps corresponding to packs which are now
695 * included in the MIDX.
696 */
697 for_each_string_list_item(item, include) {
698 strbuf_addstr(&path, item->string);
699 strbuf_strip_suffix(&path, ".idx");
700 strbuf_addstr(&path, ".bitmap");
701
702 if (unlink(path.buf) && errno != ENOENT)
703 warning_errno(_("could not remove stale bitmap: %s"),
704 path.buf);
705
706 strbuf_setlen(&path, packdir_len);
707 }
708 strbuf_release(&path);
709}
710
f9825d1c 711static int write_cruft_pack(const struct pack_objects_args *args,
c12cda47 712 const char *destination,
f9825d1c 713 const char *pack_prefix,
eddad368 714 const char *cruft_expiration,
f9825d1c
TB
715 struct string_list *names,
716 struct string_list *existing_packs,
717 struct string_list *existing_kept_packs)
718{
719 struct child_process cmd = CHILD_PROCESS_INIT;
720 struct strbuf line = STRBUF_INIT;
721 struct string_list_item *item;
722 FILE *in, *out;
723 int ret;
c12cda47
TB
724 const char *scratch;
725 int local = skip_prefix(destination, packdir, &scratch);
f9825d1c 726
c12cda47 727 prepare_pack_objects(&cmd, args, destination);
f9825d1c
TB
728
729 strvec_push(&cmd.args, "--cruft");
730 if (cruft_expiration)
731 strvec_pushf(&cmd.args, "--cruft-expiration=%s",
732 cruft_expiration);
733
734 strvec_push(&cmd.args, "--honor-pack-keep");
735 strvec_push(&cmd.args, "--non-empty");
736 strvec_push(&cmd.args, "--max-pack-size=0");
737
738 cmd.in = -1;
739
740 ret = start_command(&cmd);
741 if (ret)
742 return ret;
743
744 /*
745 * names has a confusing double use: it both provides the list
746 * of just-written new packs, and accepts the name of the cruft
747 * pack we are writing.
748 *
749 * By the time it is read here, it contains only the pack(s)
750 * that were just written, which is exactly the set of packs we
751 * want to consider kept.
91badeba
TB
752 *
753 * If `--expire-to` is given, the double-use served by `names`
754 * ensures that the pack written to `--expire-to` excludes any
755 * objects contained in the cruft pack.
f9825d1c
TB
756 */
757 in = xfdopen(cmd.in, "w");
758 for_each_string_list_item(item, names)
759 fprintf(in, "%s-%s.pack\n", pack_prefix, item->string);
760 for_each_string_list_item(item, existing_packs)
761 fprintf(in, "-%s.pack\n", item->string);
762 for_each_string_list_item(item, existing_kept_packs)
763 fprintf(in, "%s.pack\n", item->string);
764 fclose(in);
765
766 out = xfdopen(cmd.out, "r");
767 while (strbuf_getline_lf(&line, out) != EOF) {
b639606f
JK
768 struct string_list_item *item;
769
f9825d1c
TB
770 if (line.len != the_hash_algo->hexsz)
771 die(_("repack: Expecting full hex object ID lines only "
772 "from pack-objects."));
c12cda47
TB
773 /*
774 * avoid putting packs written outside of the repository in the
775 * list of names
776 */
ad909688
TB
777 if (local) {
778 item = string_list_append(names, line.buf);
779 item->util = populate_pack_exts(line.buf);
780 }
f9825d1c
TB
781 }
782 fclose(out);
783
784 strbuf_release(&line);
785
786 return finish_command(&cmd);
787}
788
a1bbc6c0
SB
789int cmd_repack(int argc, const char **argv, const char *prefix)
790{
d3180279 791 struct child_process cmd = CHILD_PROCESS_INIT;
a1bbc6c0 792 struct string_list_item *item;
a1bbc6c0 793 struct string_list names = STRING_LIST_INIT_DUP;
a169166d 794 struct string_list existing_nonkept_packs = STRING_LIST_INIT_DUP;
90f838bc 795 struct string_list existing_kept_packs = STRING_LIST_INIT_DUP;
0fabafd0 796 struct pack_geometry *geometry = NULL;
a1bbc6c0 797 struct strbuf line = STRBUF_INIT;
324efc90 798 struct tempfile *refs_snapshot = NULL;
2fcb03b5 799 int i, ext, ret;
a1bbc6c0 800 FILE *out;
47ca93d0 801 int show_progress;
a1bbc6c0
SB
802
803 /* variables to be filled by option parsing */
a1bbc6c0 804 int delete_redundant = 0;
aa8bd519 805 const char *unpack_unreachable = NULL;
905f27b8 806 int keep_unreachable = 0;
ed7e5fc3 807 struct string_list keep_pack_list = STRING_LIST_INIT_NODUP;
2b958e79 808 struct pack_objects_args po_args = {NULL};
4571324b 809 struct pack_objects_args cruft_po_args = {NULL};
0fabafd0 810 int geometric_factor = 0;
1d89d88d 811 int write_midx = 0;
eddad368 812 const char *cruft_expiration = NULL;
91badeba 813 const char *expire_to = NULL;
a1bbc6c0
SB
814
815 struct option builtin_repack_options[] = {
816 OPT_BIT('a', NULL, &pack_everything,
817 N_("pack everything in a single pack"), ALL_INTO_ONE),
818 OPT_BIT('A', NULL, &pack_everything,
819 N_("same as -a, and turn unreachable objects loose"),
820 LOOSEN_UNREACHABLE | ALL_INTO_ONE),
f9825d1c
TB
821 OPT_BIT(0, "cruft", &pack_everything,
822 N_("same as -a, pack unreachable cruft objects separately"),
823 PACK_CRUFT),
824 OPT_STRING(0, "cruft-expiration", &cruft_expiration, N_("approxidate"),
c512f311 825 N_("with --cruft, expire objects older than this")),
a1bbc6c0
SB
826 OPT_BOOL('d', NULL, &delete_redundant,
827 N_("remove redundant packs, and run git-prune-packed")),
2b958e79 828 OPT_BOOL('f', NULL, &po_args.no_reuse_delta,
a1bbc6c0 829 N_("pass --no-reuse-delta to git-pack-objects")),
2b958e79 830 OPT_BOOL('F', NULL, &po_args.no_reuse_object,
a1bbc6c0 831 N_("pass --no-reuse-object to git-pack-objects")),
64a6151d
PS
832 OPT_NEGBIT('n', NULL, &run_update_server_info,
833 N_("do not run git-update-server-info"), 1),
2b958e79
JT
834 OPT__QUIET(&po_args.quiet, N_("be quiet")),
835 OPT_BOOL('l', "local", &po_args.local,
a1bbc6c0 836 N_("pass --local to git-pack-objects")),
d078d85b 837 OPT_BOOL('b', "write-bitmap-index", &write_bitmaps,
5cf2741c 838 N_("write bitmap index")),
16d75fa4
JK
839 OPT_BOOL('i', "delta-islands", &use_delta_islands,
840 N_("pass --delta-islands to git-pack-objects")),
a1bbc6c0
SB
841 OPT_STRING(0, "unpack-unreachable", &unpack_unreachable, N_("approxidate"),
842 N_("with -A, do not loosen objects older than this")),
905f27b8
JK
843 OPT_BOOL('k', "keep-unreachable", &keep_unreachable,
844 N_("with -a, repack unreachable objects")),
2b958e79 845 OPT_STRING(0, "window", &po_args.window, N_("n"),
a1bbc6c0 846 N_("size of the window used for delta compression")),
2b958e79 847 OPT_STRING(0, "window-memory", &po_args.window_memory, N_("bytes"),
a1bbc6c0 848 N_("same as the above, but limit memory size instead of entries count")),
2b958e79 849 OPT_STRING(0, "depth", &po_args.depth, N_("n"),
a1bbc6c0 850 N_("limits the maximum delta depth")),
2b958e79 851 OPT_STRING(0, "threads", &po_args.threads, N_("n"),
40bcf318 852 N_("limits the maximum number of threads")),
2b958e79 853 OPT_STRING(0, "max-pack-size", &po_args.max_pack_size, N_("bytes"),
a1bbc6c0 854 N_("maximum size of each packfile")),
ee34a2be
JK
855 OPT_BOOL(0, "pack-kept-objects", &pack_kept_objects,
856 N_("repack objects in packs marked with .keep")),
ed7e5fc3
NTND
857 OPT_STRING_LIST(0, "keep-pack", &keep_pack_list, N_("name"),
858 N_("do not repack this pack")),
0fabafd0
TB
859 OPT_INTEGER('g', "geometric", &geometric_factor,
860 N_("find a geometric progression with factor <N>")),
1d89d88d
TB
861 OPT_BOOL('m', "write-midx", &write_midx,
862 N_("write a multi-pack index of the resulting packs")),
91badeba
TB
863 OPT_STRING(0, "expire-to", &expire_to, N_("dir"),
864 N_("pack prefix to store a pack containing pruned objects")),
a1bbc6c0
SB
865 OPT_END()
866 };
867
4571324b 868 git_config(repack_config, &cruft_po_args);
a1bbc6c0
SB
869
870 argc = parse_options(argc, argv, prefix, builtin_repack_options,
871 git_repack_usage, 0);
872
067fbd41
JK
873 if (delete_redundant && repository_format_precious_objects)
874 die(_("cannot delete packs in a precious-objects repo"));
875
905f27b8
JK
876 if (keep_unreachable &&
877 (unpack_unreachable || (pack_everything & LOOSEN_UNREACHABLE)))
12909b6b 878 die(_("options '%s' and '%s' cannot be used together"), "--keep-unreachable", "-A");
905f27b8 879
f9825d1c
TB
880 if (pack_everything & PACK_CRUFT) {
881 pack_everything |= ALL_INTO_ONE;
882
883 if (unpack_unreachable || (pack_everything & LOOSEN_UNREACHABLE))
884 die(_("options '%s' and '%s' cannot be used together"), "--cruft", "-A");
885 if (keep_unreachable)
886 die(_("options '%s' and '%s' cannot be used together"), "--cruft", "-k");
887 }
888
73284822 889 if (write_bitmaps < 0) {
1d89d88d
TB
890 if (!write_midx &&
891 (!(pack_everything & ALL_INTO_ONE) || !is_bare_repository()))
25575015 892 write_bitmaps = 0;
ff1e653c
TB
893 } else if (write_bitmaps &&
894 git_env_bool(GIT_TEST_MULTI_PACK_INDEX, 0) &&
895 git_env_bool(GIT_TEST_MULTI_PACK_INDEX_WRITE_BITMAP, 0)) {
896 write_bitmaps = 0;
73284822 897 }
ee34a2be 898 if (pack_kept_objects < 0)
e4d0c11c 899 pack_kept_objects = write_bitmaps > 0 && !write_midx;
ee34a2be 900
1d89d88d 901 if (write_bitmaps && !(pack_everything & ALL_INTO_ONE) && !write_midx)
1c409a70
DT
902 die(_(incremental_bitmap_conflict_error));
903
d85cd187
PS
904 if (write_bitmaps && po_args.local && has_alt_odb(the_repository)) {
905 /*
906 * When asked to do a local repack, but we have
907 * packfiles that are inherited from an alternate, then
908 * we cannot guarantee that the multi-pack-index would
909 * have full coverage of all objects. We thus disable
910 * writing bitmaps in that case.
911 */
912 warning(_("disabling bitmap writing, as some objects are not being packed"));
913 write_bitmaps = 0;
914 }
915
324efc90
TB
916 if (write_midx && write_bitmaps) {
917 struct strbuf path = STRBUF_INIT;
918
919 strbuf_addf(&path, "%s/%s_XXXXXX", get_object_directory(),
920 "bitmap-ref-tips");
921
922 refs_snapshot = xmks_tempfile(path.buf);
923 midx_snapshot_refs(refs_snapshot);
924
925 strbuf_release(&path);
926 }
927
4b5a808b
VD
928 packdir = mkpathdup("%s/pack", get_object_directory());
929 packtmp_name = xstrfmt(".tmp-%d-pack", (int)getpid());
930 packtmp = mkpathdup("%s/%s", packdir, packtmp_name);
931
932 collect_pack_filenames(&existing_nonkept_packs, &existing_kept_packs,
933 &keep_pack_list);
934
0fabafd0
TB
935 if (geometric_factor) {
936 if (pack_everything)
12909b6b 937 die(_("options '%s' and '%s' cannot be used together"), "--geometric", "-A/-a");
932c16c0 938 init_pack_geometry(&geometry, &existing_kept_packs, &po_args);
0fabafd0
TB
939 split_pack_geometry(geometry, geometric_factor);
940 }
941
4e7b65ba 942 prepare_pack_objects(&cmd, &po_args, packtmp);
2b958e79 943
47ca93d0
DS
944 show_progress = !po_args.quiet && isatty(2);
945
22f9b7f3 946 strvec_push(&cmd.args, "--keep-true-parents");
ee34a2be 947 if (!pack_kept_objects)
22f9b7f3 948 strvec_push(&cmd.args, "--honor-pack-keep");
ed7e5fc3 949 for (i = 0; i < keep_pack_list.nr; i++)
22f9b7f3 950 strvec_pushf(&cmd.args, "--keep-pack=%s",
f6d8942b 951 keep_pack_list.items[i].string);
22f9b7f3 952 strvec_push(&cmd.args, "--non-empty");
0fabafd0
TB
953 if (!geometry) {
954 /*
ccae01ca
JH
955 * We need to grab all reachable objects, including those that
956 * are reachable from reflogs and the index.
0fabafd0 957 *
ccae01ca
JH
958 * When repacking into a geometric progression of packs,
959 * however, we ask 'git pack-objects --stdin-packs', and it is
960 * not about packing objects based on reachability but about
961 * repacking all the objects in specified packs and loose ones
962 * (indeed, --stdin-packs is incompatible with these options).
0fabafd0
TB
963 */
964 strvec_push(&cmd.args, "--all");
965 strvec_push(&cmd.args, "--reflog");
966 strvec_push(&cmd.args, "--indexed-objects");
967 }
a5183d76 968 if (repo_has_promisor_remote(the_repository))
22f9b7f3 969 strvec_push(&cmd.args, "--exclude-promisor-objects");
1d89d88d
TB
970 if (!write_midx) {
971 if (write_bitmaps > 0)
972 strvec_push(&cmd.args, "--write-bitmap-index");
973 else if (write_bitmaps < 0)
974 strvec_push(&cmd.args, "--write-bitmap-index-quiet");
975 }
16d75fa4 976 if (use_delta_islands)
22f9b7f3 977 strvec_push(&cmd.args, "--delta-islands");
a1bbc6c0 978
90f838bc 979 if (pack_everything & ALL_INTO_ONE) {
5d19e813
JT
980 repack_promisor_objects(&po_args, &names);
981
f9825d1c
TB
982 if (existing_nonkept_packs.nr && delete_redundant &&
983 !(pack_everything & PACK_CRUFT)) {
a643157d
RS
984 for_each_string_list_item(item, &names) {
985 strvec_pushf(&cmd.args, "--keep-pack=%s-%s.pack",
986 packtmp_name, item->string);
987 }
8d422993 988 if (unpack_unreachable) {
22f9b7f3 989 strvec_pushf(&cmd.args,
f6d8942b
JK
990 "--unpack-unreachable=%s",
991 unpack_unreachable);
8d422993 992 } else if (pack_everything & LOOSEN_UNREACHABLE) {
22f9b7f3 993 strvec_push(&cmd.args,
f6d8942b 994 "--unpack-unreachable");
905f27b8 995 } else if (keep_unreachable) {
22f9b7f3
JK
996 strvec_push(&cmd.args, "--keep-unreachable");
997 strvec_push(&cmd.args, "--pack-loose-unreachable");
8d422993 998 }
a1bbc6c0 999 }
0fabafd0
TB
1000 } else if (geometry) {
1001 strvec_push(&cmd.args, "--stdin-packs");
1002 strvec_push(&cmd.args, "--unpacked");
a1bbc6c0 1003 } else {
22f9b7f3
JK
1004 strvec_push(&cmd.args, "--unpacked");
1005 strvec_push(&cmd.args, "--incremental");
a1bbc6c0
SB
1006 }
1007
0fabafd0
TB
1008 if (geometry)
1009 cmd.in = -1;
1010 else
1011 cmd.no_stdin = 1;
a1bbc6c0
SB
1012
1013 ret = start_command(&cmd);
1014 if (ret)
90428ddc 1015 goto cleanup;
a1bbc6c0 1016
0fabafd0
TB
1017 if (geometry) {
1018 FILE *in = xfdopen(cmd.in, "w");
1019 /*
1020 * The resulting pack should contain all objects in packs that
1021 * are going to be rolled up, but exclude objects in packs which
1022 * are being left alone.
1023 */
1024 for (i = 0; i < geometry->split; i++)
1025 fprintf(in, "%s\n", pack_basename(geometry->pack[i]));
1026 for (i = geometry->split; i < geometry->pack_nr; i++)
1027 fprintf(in, "^%s\n", pack_basename(geometry->pack[i]));
1028 fclose(in);
1029 }
1030
a1bbc6c0 1031 out = xfdopen(cmd.out, "r");
8f309aeb 1032 while (strbuf_getline_lf(&line, out) != EOF) {
b639606f
JK
1033 struct string_list_item *item;
1034
2f0c9e9a 1035 if (line.len != the_hash_algo->hexsz)
3813a89f 1036 die(_("repack: Expecting full hex object ID lines only from pack-objects."));
b639606f
JK
1037 item = string_list_append(&names, line.buf);
1038 item->util = populate_pack_exts(item->string);
a1bbc6c0 1039 }
b6046abc 1040 strbuf_release(&line);
a1bbc6c0
SB
1041 fclose(out);
1042 ret = finish_command(&cmd);
1043 if (ret)
90428ddc 1044 goto cleanup;
a1bbc6c0 1045
2b958e79 1046 if (!names.nr && !po_args.quiet)
c83d950e 1047 printf_ln(_("Nothing new to pack."));
a1bbc6c0 1048
f9825d1c
TB
1049 if (pack_everything & PACK_CRUFT) {
1050 const char *pack_prefix;
1051 if (!skip_prefix(packtmp, packdir, &pack_prefix))
1052 die(_("pack prefix %s does not begin with objdir %s"),
1053 packtmp, packdir);
1054 if (*pack_prefix == '/')
1055 pack_prefix++;
1056
4571324b
TB
1057 if (!cruft_po_args.window)
1058 cruft_po_args.window = po_args.window;
1059 if (!cruft_po_args.window_memory)
1060 cruft_po_args.window_memory = po_args.window_memory;
1061 if (!cruft_po_args.depth)
1062 cruft_po_args.depth = po_args.depth;
1063 if (!cruft_po_args.threads)
1064 cruft_po_args.threads = po_args.threads;
1065
1066 cruft_po_args.local = po_args.local;
1067 cruft_po_args.quiet = po_args.quiet;
1068
c12cda47 1069 ret = write_cruft_pack(&cruft_po_args, packtmp, pack_prefix,
eddad368 1070 cruft_expiration, &names,
f9825d1c
TB
1071 &existing_nonkept_packs,
1072 &existing_kept_packs);
1073 if (ret)
90428ddc 1074 goto cleanup;
91badeba
TB
1075
1076 if (delete_redundant && expire_to) {
1077 /*
1078 * If `--expire-to` is given with `-d`, it's possible
1079 * that we're about to prune some objects. With cruft
1080 * packs, pruning is implicit: any objects from existing
1081 * packs that weren't picked up by new packs are removed
1082 * when their packs are deleted.
1083 *
1084 * Generate an additional cruft pack, with one twist:
1085 * `names` now includes the name of the cruft pack
1086 * written in the previous step. So the contents of
1087 * _this_ cruft pack exclude everything contained in the
1088 * existing cruft pack (that is, all of the unreachable
1089 * objects which are no older than
1090 * `--cruft-expiration`).
1091 *
1092 * To make this work, cruft_expiration must become NULL
1093 * so that this cruft pack doesn't actually prune any
1094 * objects. If it were non-NULL, this call would always
1095 * generate an empty pack (since every object not in the
1096 * cruft pack generated above will have an mtime older
1097 * than the expiration).
1098 */
1099 ret = write_cruft_pack(&cruft_po_args, expire_to,
1100 pack_prefix,
1101 NULL,
1102 &names,
1103 &existing_nonkept_packs,
1104 &existing_kept_packs);
1105 if (ret)
90428ddc 1106 goto cleanup;
91badeba 1107 }
f9825d1c
TB
1108 }
1109
66731ff9
TB
1110 string_list_sort(&names);
1111
2d511cfc 1112 close_object_store(the_repository->objects);
5bdece0d 1113
a1bbc6c0
SB
1114 /*
1115 * Ok we have prepared all new packfiles.
a1bbc6c0 1116 */
a1bbc6c0 1117 for_each_string_list_item(item, &names) {
d3d9c519
JK
1118 struct generated_pack_data *data = item->util;
1119
b328c216 1120 for (ext = 0; ext < ARRAY_SIZE(exts); ext++) {
9cf10d87 1121 char *fname;
525e18c0 1122
a1bbc6c0 1123 fname = mkpathdup("%s/pack-%s%s",
42a02d85 1124 packdir, item->string, exts[ext].name);
2fcb03b5 1125
9cf10d87
JK
1126 if (data->tempfiles[ext]) {
1127 const char *fname_old = get_tempfile_path(data->tempfiles[ext]);
2fcb03b5 1128 struct stat statbuffer;
9cf10d87 1129
2fcb03b5
TB
1130 if (!stat(fname_old, &statbuffer)) {
1131 statbuffer.st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
1132 chmod(fname_old, statbuffer.st_mode);
1133 }
1134
9cf10d87
JK
1135 if (rename_tempfile(&data->tempfiles[ext], fname))
1136 die_errno(_("renaming pack to '%s' failed"), fname);
2fcb03b5 1137 } else if (!exts[ext].optional)
a4880b20
JK
1138 die(_("pack-objects did not write a '%s' file for pack %s-%s"),
1139 exts[ext].name, packtmp, item->string);
2fcb03b5
TB
1140 else if (unlink(fname) < 0 && errno != ENOENT)
1141 die_errno(_("could not unlink: %s"), fname);
a1bbc6c0 1142
e3cf2303 1143 free(fname);
a1bbc6c0
SB
1144 }
1145 }
a1bbc6c0
SB
1146 /* End of pack replacement. */
1147
1d89d88d 1148 if (delete_redundant && pack_everything & ALL_INTO_ONE) {
2f0c9e9a 1149 const int hexsz = the_hash_algo->hexsz;
1d89d88d 1150 for_each_string_list_item(item, &existing_nonkept_packs) {
a1bbc6c0
SB
1151 char *sha1;
1152 size_t len = strlen(item->string);
2f0c9e9a 1153 if (len < hexsz)
a1bbc6c0 1154 continue;
2f0c9e9a 1155 sha1 = item->string + len - hexsz;
1d89d88d
TB
1156 /*
1157 * Mark this pack for deletion, which ensures that this
1158 * pack won't be included in a MIDX (if `--write-midx`
1159 * was given) and that we will actually delete this pack
1160 * (if `-d` was given).
1161 */
72263ffc
TB
1162 if (!string_list_has_string(&names, sha1))
1163 item->util = (void*)(uintptr_t)((size_t)item->util | DELETE_PACK);
1d89d88d
TB
1164 }
1165 }
1166
1167 if (write_midx) {
1168 struct string_list include = STRING_LIST_INIT_NODUP;
1169 midx_included_packs(&include, &existing_nonkept_packs,
1170 &existing_kept_packs, &names, geometry);
1171
6d08b9d4 1172 ret = write_midx_included_packs(&include, geometry,
324efc90 1173 refs_snapshot ? get_tempfile_path(refs_snapshot) : NULL,
1d89d88d
TB
1174 show_progress, write_bitmaps > 0);
1175
55d902cd
TB
1176 if (!ret && write_bitmaps)
1177 remove_redundant_bitmaps(&include, packdir);
1178
1d89d88d
TB
1179 string_list_clear(&include, 0);
1180
1181 if (ret)
90428ddc 1182 goto cleanup;
1d89d88d
TB
1183 }
1184
5d19e813
JT
1185 reprepare_packed_git(the_repository);
1186
a1bbc6c0 1187 if (delete_redundant) {
4489a480 1188 int opts = 0;
1d89d88d 1189 for_each_string_list_item(item, &existing_nonkept_packs) {
72263ffc 1190 if (!((uintptr_t)item->util & DELETE_PACK))
1d89d88d
TB
1191 continue;
1192 remove_redundant_pack(packdir, item->string);
a1bbc6c0 1193 }
0fabafd0
TB
1194
1195 if (geometry) {
1196 struct strbuf buf = STRBUF_INIT;
1197
1198 uint32_t i;
1199 for (i = 0; i < geometry->split; i++) {
1200 struct packed_git *p = geometry->pack[i];
1201 if (string_list_has_string(&names,
1202 hash_to_hex(p->hash)))
1203 continue;
1204
1205 strbuf_reset(&buf);
1206 strbuf_addstr(&buf, pack_basename(p));
1207 strbuf_strip_suffix(&buf, ".pack");
1208
197443e8
TB
1209 if ((p->pack_keep) ||
1210 (string_list_has_string(&existing_kept_packs,
1211 buf.buf)))
1212 continue;
1213
0fabafd0
TB
1214 remove_redundant_pack(packdir, buf.buf);
1215 }
1216 strbuf_release(&buf);
1217 }
47ca93d0 1218 if (show_progress)
4489a480
RS
1219 opts |= PRUNE_PACKED_VERBOSE;
1220 prune_packed_objects(opts);
5dcfbf56
JS
1221
1222 if (!keep_unreachable &&
1223 (!(pack_everything & LOOSEN_UNREACHABLE) ||
1224 unpack_unreachable) &&
1225 is_repository_shallow(the_repository))
1226 prune_shallow(PRUNE_QUICK);
a1bbc6c0
SB
1227 }
1228
64a6151d 1229 if (run_update_server_info)
4489a480 1230 update_server_info(0);
0465a505 1231
ff1e653c
TB
1232 if (git_env_bool(GIT_TEST_MULTI_PACK_INDEX, 0)) {
1233 unsigned flags = 0;
1234 if (git_env_bool(GIT_TEST_MULTI_PACK_INDEX_WRITE_BITMAP, 0))
1235 flags |= MIDX_WRITE_BITMAP | MIDX_WRITE_REV_INDEX;
08944d1c 1236 write_midx_file(get_object_directory(), NULL, NULL, flags);
ff1e653c 1237 }
0465a505 1238
90428ddc 1239cleanup:
d3d9c519 1240 string_list_clear(&names, 1);
a169166d 1241 string_list_clear(&existing_nonkept_packs, 0);
90f838bc 1242 string_list_clear(&existing_kept_packs, 0);
0fabafd0 1243 clear_pack_geometry(geometry);
a1bbc6c0 1244
90428ddc 1245 return ret;
a1bbc6c0 1246}