Coverage Report

Created: 2026-11-12 06:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/git/odb/source-packed.c
Line
Count
Source
1
#include "git-compat-util.h"
2
#include "abspath.h"
3
#include "chdir-notify.h"
4
#include "dir.h"
5
#include "gettext.h"
6
#include "fsck.h"
7
#include "git-zlib.h"
8
#include "hex.h"
9
#include "list-objects-filter-options.h"
10
#include "mergesort.h"
11
#include "midx.h"
12
#include "odb/source-packed.h"
13
#include "odb/streaming.h"
14
#include "pack.h"
15
#include "pack-revindex.h"
16
#include "packfile.h"
17
#include "pack-bitmap.h"
18
#include "strbuf.h"
19
#include "progress.h"
20
#include "run-command.h"
21
22
static int find_pack_entry(struct odb_source_packed *store,
23
         const struct object_id *oid,
24
         struct pack_entry *e,
25
         enum object_info_flags flags,
26
         struct packed_git **bad_pack)
27
0
{
28
0
  struct packfile_list_entry *l;
29
0
  enum midx_fill_result midx_result = MIDX_FILL_MISS;
30
31
0
  odb_source_prepare(&store->base, 0);
32
0
  if (store->midx) {
33
0
    midx_result = midx_fill_entry(store->midx, oid, e, bad_pack);
34
0
    if (midx_result == MIDX_FILL_HIT)
35
0
      return 1;
36
0
  }
37
38
0
  for (l = store->packs.head; l; l = l->next) {
39
0
    struct packed_git *p = l->pack;
40
41
0
    if (!p->multi_pack_index && packfile_fill_entry(p, oid, e, bad_pack)) {
42
0
      if (!store->skip_mru_updates)
43
0
        packfile_list_prepend(&store->packs, p);
44
0
      return 1;
45
0
    }
46
0
  }
47
48
  /*
49
   * Recovery for a concurrent-repack race: a stale MIDX may still name a
50
   * vanished owning pack even though the object survives in another pack
51
   * the same MIDX covers.  The regular fallback above skips MIDX-covered
52
   * packs, and repreparing the on-disk pack set does not reload the
53
   * borrowed, cached MIDX, so scan its packs directly for the survivor.
54
   *
55
   * Skip the scan for quick lookups, which are expected to accept false
56
   * negatives in favor of speed.
57
   */
58
0
  if (midx_result == MIDX_FILL_OWNER_UNAVAILABLE &&
59
0
      !(flags & OBJECT_INFO_QUICK)) {
60
0
    struct multi_pack_index *m = store->midx;
61
0
    uint32_t i;
62
63
0
    for (i = 0; i < m->num_packs + m->num_packs_in_base; i++) {
64
0
      struct packed_git *p;
65
66
0
      if (prepare_midx_pack(m, i))
67
0
        continue;
68
0
      p = nth_midxed_pack(m, i);
69
0
      if (p && packfile_fill_entry(p, oid, e, bad_pack))
70
0
        return 1;
71
0
    }
72
0
  }
73
74
0
  return 0;
75
0
}
76
77
static enum odb_read_status odb_source_packed_read_object_info(struct odb_source *source,
78
                     const struct object_id *oid,
79
                     struct object_info *oi,
80
                     enum object_info_flags flags,
81
                     struct strbuf *errmsg)
82
0
{
83
0
  struct odb_source_packed *packed = odb_source_packed_downcast(source);
84
0
  struct packed_git *bad_pack = NULL;
85
0
  struct pack_entry e;
86
0
  int ret;
87
88
0
  if (!find_pack_entry(packed, oid, &e, flags, &bad_pack)) {
89
    /*
90
     * The lookup may have failed because the object is known to be
91
     * corrupt in one of the packfiles. Report the object as
92
     * corrupt instead of missing in that case.
93
     */
94
0
    if (bad_pack) {
95
0
      ret = -1;
96
0
      goto out;
97
0
    }
98
99
0
    ret = ODB_READ_NOT_FOUND;
100
0
    goto out;
101
0
  }
102
103
  /*
104
   * We know that the caller doesn't actually need the
105
   * information below, so return early.
106
   */
107
0
  if (!oi) {
108
0
    ret = 0;
109
0
    goto out;
110
0
  }
111
112
0
  ret = packed_object_info(packed, e.p, e.offset, oi);
113
0
  if (ret < 0) {
114
0
    bad_pack = e.p;
115
0
    mark_bad_packed_object(e.p, oid);
116
0
    goto out;
117
0
  }
118
119
0
  ret = 0;
120
121
0
out:
122
0
  if (ret < 0 && bad_pack && errmsg)
123
0
    strbuf_addf(errmsg, _("packed object %s (stored in %s) is corrupt"),
124
0
          oid_to_hex(oid), bad_pack->pack_name);
125
126
0
  return ret;
127
0
}
128
129
static int odb_source_packed_read_object_stream(struct odb_stream **out,
130
            struct odb_source *source,
131
            const struct object_id *oid)
132
0
{
133
0
  struct odb_source_packed *packed = odb_source_packed_downcast(source);
134
0
  struct pack_entry e;
135
136
0
  if (!find_pack_entry(packed, oid, &e, 0, NULL))
137
0
    return -1;
138
139
0
  return packfile_read_object_stream(out, oid, e.p, e.offset);
140
0
}
141
142
struct odb_source_packed_for_each_object_wrapper_data {
143
  struct odb_source_packed *store;
144
  const struct object_info *request;
145
  odb_for_each_object_cb cb;
146
  void *cb_data;
147
};
148
149
static int odb_source_packed_for_each_object_wrapper(const struct object_id *oid,
150
                 struct packed_git *pack,
151
                 uint32_t index_pos,
152
                 void *cb_data)
153
0
{
154
0
  struct odb_source_packed_for_each_object_wrapper_data *data = cb_data;
155
156
0
  if (data->request) {
157
0
    off_t offset = nth_packed_object_offset(pack, index_pos);
158
0
    struct object_info oi = *data->request;
159
160
0
    if (packed_object_info_with_index_pos(data->store, pack, offset,
161
0
                  &index_pos, &oi) < 0) {
162
0
      mark_bad_packed_object(pack, oid);
163
0
      return -1;
164
0
    }
165
166
0
    return data->cb(oid, &oi, data->cb_data);
167
0
  } else {
168
0
    return data->cb(oid, NULL, data->cb_data);
169
0
  }
170
0
}
171
172
static int match_hash(unsigned len, const unsigned char *a, const unsigned char *b)
173
0
{
174
0
  do {
175
0
    if (*a != *b)
176
0
      return 0;
177
0
    a++;
178
0
    b++;
179
0
    len -= 2;
180
0
  } while (len > 1);
181
0
  if (len)
182
0
    if ((*a ^ *b) & 0xf0)
183
0
      return 0;
184
0
  return 1;
185
0
}
186
187
static bool should_exclude_pack(struct packed_git *p, enum odb_for_each_object_flags flags)
188
0
{
189
0
  if ((flags & ODB_FOR_EACH_OBJECT_LOCAL_ONLY) && !p->pack_local)
190
0
    return true;
191
0
  if ((flags & ODB_FOR_EACH_OBJECT_PROMISOR_ONLY) &&
192
0
      !p->pack_promisor)
193
0
    return true;
194
0
  if ((flags & ODB_FOR_EACH_OBJECT_SKIP_IN_CORE_KEPT_PACKS) &&
195
0
      p->pack_keep_in_core)
196
0
    return true;
197
0
  if ((flags & ODB_FOR_EACH_OBJECT_SKIP_ON_DISK_KEPT_PACKS) &&
198
0
      p->pack_keep)
199
0
    return true;
200
0
  return false;
201
0
}
202
203
static int for_each_prefixed_object_in_midx(
204
  struct odb_source_packed *source,
205
  struct multi_pack_index *m,
206
  const struct odb_for_each_object_options *opts,
207
  struct odb_source_packed_for_each_object_wrapper_data *data)
208
0
{
209
0
  bool pack_errors = false;
210
0
  int ret;
211
212
0
  for (; m; m = m->base_midx) {
213
0
    uint32_t num, i, first = 0;
214
0
    int len = opts->prefix_hex_len > m->source->base.odb->repo->hash_algo->hexsz ?
215
0
      m->source->base.odb->repo->hash_algo->hexsz : opts->prefix_hex_len;
216
217
0
    if (!m->num_objects)
218
0
      continue;
219
220
0
    num = m->num_objects + m->num_objects_in_base;
221
222
0
    bsearch_one_midx(opts->prefix, m, &first);
223
224
    /*
225
     * At this point, "first" is the location of the lowest
226
     * object with an object name that could match "opts->prefix".
227
     * See if we have 0, 1 or more objects that actually match(es).
228
     */
229
0
    for (i = first; i < num; i++) {
230
0
      const struct object_id *current = NULL;
231
0
      struct packed_git *pack;
232
0
      struct object_id oid;
233
234
0
      current = nth_midxed_object_oid(&oid, m, i);
235
236
0
      if (!match_hash(len, opts->prefix->hash, current->hash))
237
0
        break;
238
239
0
      if (opts->flags || data->request) {
240
0
        uint32_t pack_id = nth_midxed_pack_int_id(m, i);
241
242
0
        if (prepare_midx_pack(m, pack_id)) {
243
0
          pack_errors = true;
244
0
          continue;
245
0
        }
246
247
0
        pack = nth_midxed_pack(m, pack_id);
248
0
        if (should_exclude_pack(pack, opts->flags))
249
0
          continue;
250
0
      }
251
252
0
      if (data->request) {
253
0
        struct object_info oi = *data->request;
254
0
        off_t offset = nth_midxed_offset(m, i);
255
256
0
        ret = packed_object_info(source, pack, offset, &oi);
257
0
        if (ret)
258
0
          goto out;
259
260
0
        ret = data->cb(&oid, &oi, data->cb_data);
261
0
        if (ret)
262
0
          goto out;
263
0
      } else {
264
0
        ret = data->cb(&oid, NULL, data->cb_data);
265
0
        if (ret)
266
0
          goto out;
267
0
      }
268
0
    }
269
0
  }
270
271
0
  ret = 0;
272
273
0
out:
274
0
  if (!ret && pack_errors)
275
0
    ret = -1;
276
0
  return ret;
277
0
}
278
279
static int for_each_prefixed_object_in_pack(
280
  struct odb_source_packed *source,
281
  struct packed_git *p,
282
  const struct odb_for_each_object_options *opts,
283
  struct odb_source_packed_for_each_object_wrapper_data *data)
284
0
{
285
0
  uint32_t num, i, first = 0;
286
0
  int len = opts->prefix_hex_len > p->repo->hash_algo->hexsz ?
287
0
    p->repo->hash_algo->hexsz : opts->prefix_hex_len;
288
0
  int ret;
289
290
0
  num = p->num_objects;
291
0
  bsearch_pack(opts->prefix, p, &first);
292
293
  /*
294
   * At this point, "first" is the location of the lowest object
295
   * with an object name that could match "bin_pfx".  See if we have
296
   * 0, 1 or more objects that actually match(es).
297
   */
298
0
  for (i = first; i < num; i++) {
299
0
    struct object_id oid;
300
301
0
    nth_packed_object_id(&oid, p, i);
302
0
    if (!match_hash(len, opts->prefix->hash, oid.hash))
303
0
      break;
304
305
0
    if (data->request) {
306
0
      struct object_info oi = *data->request;
307
0
      off_t offset = nth_packed_object_offset(p, i);
308
309
0
      ret = packed_object_info(source, p, offset, &oi);
310
0
      if (ret)
311
0
        goto out;
312
313
0
      ret = data->cb(&oid, &oi, data->cb_data);
314
0
      if (ret)
315
0
        goto out;
316
0
    } else {
317
0
      ret = data->cb(&oid, NULL, data->cb_data);
318
0
      if (ret)
319
0
        goto out;
320
0
    }
321
0
  }
322
323
0
  ret = 0;
324
325
0
out:
326
0
  return ret;
327
0
}
328
329
static int odb_source_packed_for_each_prefixed_object(
330
  struct odb_source_packed *store,
331
  const struct odb_for_each_object_options *opts,
332
  struct odb_source_packed_for_each_object_wrapper_data *data)
333
0
{
334
0
  struct packfile_list_entry *e;
335
0
  struct multi_pack_index *m;
336
0
  bool pack_errors = false;
337
0
  int ret;
338
339
0
  store->skip_mru_updates = true;
340
341
0
  m = get_multi_pack_index(store);
342
0
  if (m) {
343
0
    ret = for_each_prefixed_object_in_midx(store, m, opts, data);
344
0
    if (ret)
345
0
      goto out;
346
0
  }
347
348
0
  for (e = packfile_store_get_packs(store); e; e = e->next) {
349
0
    if (e->pack->multi_pack_index)
350
0
      continue;
351
0
    if (should_exclude_pack(e->pack, opts->flags))
352
0
      continue;
353
354
0
    if (open_pack_index(e->pack)) {
355
0
      pack_errors = true;
356
0
      continue;
357
0
    }
358
359
0
    if (!e->pack->num_objects)
360
0
      continue;
361
362
0
    ret = for_each_prefixed_object_in_pack(store, e->pack, opts, data);
363
0
    if (ret)
364
0
      goto out;
365
0
  }
366
367
0
  ret = 0;
368
369
0
out:
370
0
  store->skip_mru_updates = false;
371
0
  if (!ret && pack_errors)
372
0
    ret = -1;
373
0
  return ret;
374
0
}
375
376
struct bitmapped_for_each_object_data {
377
  struct odb_source_packed *packed;
378
  const struct object_info *request;
379
  const struct odb_for_each_object_options *opts;
380
  odb_for_each_object_cb cb;
381
  void *cb_data;
382
};
383
384
static int bitmapped_for_each_object(const struct object_id *oid,
385
             enum object_type type UNUSED,
386
             int flags UNUSED,
387
             uint32_t hash UNUSED,
388
             struct packed_git *pack,
389
             off_t offset,
390
             void *cb_data)
391
0
{
392
0
  struct bitmapped_for_each_object_data *data = cb_data;
393
394
0
  if (should_exclude_pack(pack, data->opts->flags))
395
0
    return 0;
396
397
0
  if (data->request) {
398
0
    struct object_info oi = *data->request;
399
0
    if (packed_object_info(data->packed, pack, offset, &oi) < 0)
400
0
      return -1;
401
0
    return data->cb(oid, &oi, data->cb_data);
402
0
  }
403
404
0
  return data->cb(oid, NULL, data->cb_data);
405
0
}
406
407
static int odb_source_packed_for_each_object(struct odb_source *source,
408
               const struct object_info *request,
409
               odb_for_each_object_cb cb,
410
               void *cb_data,
411
               const struct odb_for_each_object_options *opts)
412
0
{
413
0
  struct odb_source_packed *packed = odb_source_packed_downcast(source);
414
0
  struct odb_source_packed_for_each_object_wrapper_data data = {
415
0
    .store = packed,
416
0
    .request = request,
417
0
    .cb = cb,
418
0
    .cb_data = cb_data,
419
0
  };
420
0
  struct bitmap_index *bitmap = NULL;
421
0
  struct packfile_list_entry *e;
422
0
  int pack_errors = 0, ret;
423
424
0
  if (opts->prefix)
425
0
    return odb_source_packed_for_each_prefixed_object(packed, opts, &data);
426
427
0
  if (opts->filter &&
428
0
      opts->filter->choice != LOFC_DISABLED &&
429
0
      can_filter_bitmap(opts->filter))
430
0
    bitmap = prepare_bitmap_git_for_source(packed);
431
0
  if (bitmap) {
432
0
    struct bitmapped_for_each_object_data bitmap_data = {
433
0
      .packed = packed,
434
0
      .request = request,
435
0
      .opts = opts,
436
0
      .cb = cb,
437
0
      .cb_data = cb_data,
438
0
    };
439
440
0
    ret = for_each_bitmapped_object(bitmap, opts->filter,
441
0
            bitmapped_for_each_object,
442
0
            &bitmap_data);
443
0
    if (ret)
444
0
      goto out;
445
0
  }
446
447
0
  packed->skip_mru_updates = true;
448
449
0
  for (e = packfile_store_get_packs(packed); e; e = e->next) {
450
0
    struct packed_git *p = e->pack;
451
452
0
    if (should_exclude_pack(p, opts->flags))
453
0
      continue;
454
455
    /*
456
     * Objects covered by the bitmap have already been yielded
457
     * above; skip them here to avoid duplicates.
458
     */
459
0
    if (bitmap && bitmap_index_contains_pack(bitmap, p))
460
0
      continue;
461
462
0
    if (open_pack_index(p)) {
463
0
      pack_errors = 1;
464
0
      continue;
465
0
    }
466
467
0
    ret = for_each_object_in_pack(p, odb_source_packed_for_each_object_wrapper,
468
0
                &data, opts->flags);
469
0
    if (ret)
470
0
      goto out;
471
0
  }
472
473
0
  ret = 0;
474
475
0
out:
476
0
  packed->skip_mru_updates = false;
477
0
  free_bitmap_index(bitmap);
478
479
0
  if (!ret && pack_errors)
480
0
    ret = -1;
481
0
  return ret;
482
0
}
483
484
static int odb_source_packed_count_objects(struct odb_source *source,
485
             enum odb_count_objects_flags flags UNUSED,
486
             unsigned long *out)
487
0
{
488
0
  struct odb_source_packed *packed = odb_source_packed_downcast(source);
489
0
  struct packfile_list_entry *e;
490
0
  struct multi_pack_index *m;
491
0
  unsigned long count = 0;
492
0
  int ret;
493
494
0
  m = get_multi_pack_index(packed);
495
0
  if (m)
496
0
    count += m->num_objects + m->num_objects_in_base;
497
498
0
  for (e = packfile_store_get_packs(packed); e; e = e->next) {
499
0
    if (e->pack->multi_pack_index)
500
0
      continue;
501
0
    if (open_pack_index(e->pack)) {
502
0
      ret = -1;
503
0
      goto out;
504
0
    }
505
506
0
    count += e->pack->num_objects;
507
0
  }
508
509
0
  *out = count;
510
0
  ret = 0;
511
512
0
out:
513
0
  return ret;
514
0
}
515
516
static int extend_abbrev_len(const struct object_id *a,
517
           const struct object_id *b,
518
           unsigned *out)
519
0
{
520
0
  unsigned len = oid_common_prefix_hexlen(a, b);
521
0
  if (len != hash_algos[a->algo].hexsz && len >= *out)
522
0
    *out = len + 1;
523
0
  return 0;
524
0
}
525
526
static void find_abbrev_len_for_midx(struct multi_pack_index *m,
527
             const struct object_id *oid,
528
             unsigned min_len,
529
             unsigned *out)
530
0
{
531
0
  unsigned len = min_len;
532
533
0
  for (; m; m = m->base_midx) {
534
0
    int match = 0;
535
0
    uint32_t num, first = 0;
536
0
    struct object_id found_oid;
537
538
0
    if (!m->num_objects)
539
0
      continue;
540
541
0
    num = m->num_objects + m->num_objects_in_base;
542
0
    match = bsearch_one_midx(oid, m, &first);
543
544
    /*
545
     * first is now the position in the packfile where we
546
     * would insert the object ID if it does not exist (or the
547
     * position of the object ID if it does exist). Hence, we
548
     * consider a maximum of two objects nearby for the
549
     * abbreviation length.
550
     */
551
552
0
    if (!match) {
553
0
      if (nth_midxed_object_oid(&found_oid, m, first))
554
0
        extend_abbrev_len(&found_oid, oid, &len);
555
0
    } else if (first < num - 1) {
556
0
      if (nth_midxed_object_oid(&found_oid, m, first + 1))
557
0
        extend_abbrev_len(&found_oid, oid, &len);
558
0
    }
559
0
    if (first > 0) {
560
0
      if (nth_midxed_object_oid(&found_oid, m, first - 1))
561
0
        extend_abbrev_len(&found_oid, oid, &len);
562
0
    }
563
0
  }
564
565
0
  *out = len;
566
0
}
567
568
static void find_abbrev_len_for_pack(struct packed_git *p,
569
             const struct object_id *oid,
570
             unsigned min_len,
571
             unsigned *out)
572
0
{
573
0
  int match;
574
0
  uint32_t num, first = 0;
575
0
  struct object_id found_oid;
576
0
  unsigned len = min_len;
577
578
0
  num = p->num_objects;
579
0
  match = bsearch_pack(oid, p, &first);
580
581
  /*
582
   * first is now the position in the packfile where we would insert
583
   * the object ID if it does not exist (or the position of mad->hash if
584
   * it does exist). Hence, we consider a maximum of two objects
585
   * nearby for the abbreviation length.
586
   */
587
0
  if (!match) {
588
0
    if (!nth_packed_object_id(&found_oid, p, first))
589
0
      extend_abbrev_len(&found_oid, oid, &len);
590
0
  } else if (first < num - 1) {
591
0
    if (!nth_packed_object_id(&found_oid, p, first + 1))
592
0
      extend_abbrev_len(&found_oid, oid, &len);
593
0
  }
594
0
  if (first > 0) {
595
0
    if (!nth_packed_object_id(&found_oid, p, first - 1))
596
0
      extend_abbrev_len(&found_oid, oid, &len);
597
0
  }
598
599
0
  *out = len;
600
0
}
601
602
static int odb_source_packed_find_abbrev_len(struct odb_source *source,
603
               const struct object_id *oid,
604
               unsigned min_len,
605
               unsigned *out)
606
0
{
607
0
  struct odb_source_packed *packed = odb_source_packed_downcast(source);
608
0
  struct packfile_list_entry *e;
609
0
  struct multi_pack_index *m;
610
611
0
  m = get_multi_pack_index(packed);
612
0
  if (m)
613
0
    find_abbrev_len_for_midx(m, oid, min_len, &min_len);
614
615
0
  for (e = packfile_store_get_packs(packed); e; e = e->next) {
616
0
    if (e->pack->multi_pack_index)
617
0
      continue;
618
0
    if (open_pack_index(e->pack) || !e->pack->num_objects)
619
0
      continue;
620
621
0
    find_abbrev_len_for_pack(e->pack, oid, min_len, &min_len);
622
0
  }
623
624
0
  *out = min_len;
625
0
  return 0;
626
0
}
627
628
static int odb_source_packed_freshen_object(struct odb_source *source,
629
              const struct object_id *oid,
630
              const time_t *mtime)
631
0
{
632
0
  struct odb_source_packed *packed = odb_source_packed_downcast(source);
633
0
  struct utimbuf times, *timesp = NULL;
634
0
  struct pack_entry e;
635
636
0
  if (mtime) {
637
0
    times.actime = *mtime;
638
0
    times.modtime = *mtime;
639
0
    timesp = &times;
640
0
  }
641
642
0
  if (!find_pack_entry(packed, oid, &e, 0, NULL))
643
0
    return 0;
644
0
  if (e.p->is_cruft)
645
0
    return 0;
646
0
  if (e.p->freshened)
647
0
    return 1;
648
0
  if (utime(e.p->pack_name, timesp))
649
0
    return 0;
650
0
  e.p->freshened = 1;
651
652
0
  return 1;
653
0
}
654
655
static int odb_source_packed_write_object(struct odb_source *source UNUSED,
656
            const void *buf UNUSED,
657
            size_t len UNUSED,
658
            enum object_type type UNUSED,
659
            const struct object_id *oid UNUSED,
660
            const struct object_id *compat_oid UNUSED,
661
            const time_t *mtime UNUSED,
662
            unsigned flags UNUSED)
663
0
{
664
0
  return error("packed backend cannot write objects");
665
0
}
666
667
static int odb_source_packed_write_object_stream(struct odb_source *source UNUSED,
668
             struct odb_stream *stream UNUSED,
669
             struct object_id *oid UNUSED)
670
0
{
671
0
  return error("packed backend cannot write object streams");
672
0
}
673
674
static int odb_source_packed_begin_transaction(struct odb_source *source UNUSED,
675
                 struct odb_transaction **out UNUSED,
676
                 enum odb_transaction_flags flags UNUSED)
677
0
{
678
0
  return error("packed backend cannot begin transactions");
679
0
}
680
681
void (*report_garbage)(unsigned seen_bits, const char *path);
682
683
static void report_helper(const struct string_list *list,
684
        int seen_bits, int first, int last)
685
0
{
686
0
  if (seen_bits == (PACKDIR_FILE_PACK|PACKDIR_FILE_IDX))
687
0
    return;
688
689
0
  for (; first < last; first++)
690
0
    report_garbage(seen_bits, list->items[first].string);
691
0
}
692
693
static void report_pack_garbage(struct string_list *list)
694
0
{
695
0
  int baselen = -1, first = 0, seen_bits = 0;
696
697
0
  if (!report_garbage)
698
0
    return;
699
700
0
  string_list_sort(list);
701
702
0
  for (size_t i = 0; i < list->nr; i++) {
703
0
    const char *path = list->items[i].string;
704
0
    if (baselen != -1 &&
705
0
        strncmp(path, list->items[first].string, baselen)) {
706
0
      report_helper(list, seen_bits, first, i);
707
0
      baselen = -1;
708
0
      seen_bits = 0;
709
0
    }
710
0
    if (baselen == -1) {
711
0
      const char *dot = strrchr(path, '.');
712
0
      if (!dot) {
713
0
        report_garbage(PACKDIR_FILE_GARBAGE, path);
714
0
        continue;
715
0
      }
716
0
      baselen = dot - path + 1;
717
0
      first = i;
718
0
    }
719
0
    if (!strcmp(path + baselen, "pack"))
720
0
      seen_bits |= 1;
721
0
    else if (!strcmp(path + baselen, "idx"))
722
0
      seen_bits |= 2;
723
0
  }
724
0
  report_helper(list, seen_bits, first, list->nr);
725
0
}
726
727
struct prepare_pack_data {
728
  struct odb_source_packed *source;
729
  struct string_list *garbage;
730
};
731
732
static void prepare_pack(const char *full_name, size_t full_name_len,
733
       const char *file_name, void *_data)
734
0
{
735
0
  struct prepare_pack_data *data = (struct prepare_pack_data *)_data;
736
0
  size_t base_len = full_name_len;
737
738
0
  if (strip_suffix_mem(full_name, &base_len, ".idx") &&
739
0
      !(data->source->midx &&
740
0
        midx_contains_pack(data->source->midx, file_name))) {
741
0
    char *trimmed_path = xstrndup(full_name, full_name_len);
742
0
    packfile_store_load_pack(data->source,
743
0
           trimmed_path, data->source->local);
744
0
    free(trimmed_path);
745
0
  }
746
747
0
  if (!report_garbage)
748
0
    return;
749
750
0
  if (!strcmp(file_name, "multi-pack-index") ||
751
0
      !strcmp(file_name, "multi-pack-index.d"))
752
0
    return;
753
0
  if (starts_with(file_name, "multi-pack-index") &&
754
0
      (ends_with(file_name, ".bitmap") || ends_with(file_name, ".rev")))
755
0
    return;
756
0
  if (ends_with(file_name, ".idx") ||
757
0
      ends_with(file_name, ".rev") ||
758
0
      ends_with(file_name, ".pack") ||
759
0
      ends_with(file_name, ".bitmap") ||
760
0
      ends_with(file_name, ".keep") ||
761
0
      ends_with(file_name, ".promisor") ||
762
0
      ends_with(file_name, ".mtimes"))
763
0
    string_list_append(data->garbage, full_name);
764
0
  else
765
0
    report_garbage(PACKDIR_FILE_GARBAGE, full_name);
766
0
}
767
768
static void prepare_packed_git_one(struct odb_source_packed *source)
769
0
{
770
0
  struct string_list garbage = STRING_LIST_INIT_DUP;
771
0
  struct prepare_pack_data data = {
772
0
    .source = source,
773
0
    .garbage = &garbage,
774
0
  };
775
776
0
  for_each_file_in_pack_dir(source->base.path, prepare_pack, &data);
777
778
0
  report_pack_garbage(data.garbage);
779
0
  string_list_clear(data.garbage, 0);
780
0
}
781
782
0
DEFINE_LIST_SORT(static, sort_packs, struct packfile_list_entry, next);
783
0
784
0
static int sort_pack(const struct packfile_list_entry *a,
785
0
         const struct packfile_list_entry *b)
786
0
{
787
0
  int st;
788
789
  /*
790
   * Local packs tend to contain objects specific to our
791
   * variant of the project than remote ones.  In addition,
792
   * remote ones could be on a network mounted filesystem.
793
   * Favor local ones for these reasons.
794
   */
795
0
  st = a->pack->pack_local - b->pack->pack_local;
796
0
  if (st)
797
0
    return -st;
798
799
  /*
800
   * Younger packs tend to contain more recent objects,
801
   * and more recent objects tend to get accessed more
802
   * often.
803
   */
804
0
  if (a->pack->mtime < b->pack->mtime)
805
0
    return 1;
806
0
  else if (a->pack->mtime == b->pack->mtime)
807
0
    return 0;
808
0
  return -1;
809
0
}
810
811
static void odb_source_packed_prepare(struct odb_source *source,
812
              enum odb_prepare_flags flags)
813
0
{
814
0
  struct odb_source_packed *packed = odb_source_packed_downcast(source);
815
816
0
  if (flags & ODB_PREPARE_FLUSH_CACHES)
817
0
    packed->initialized = false;
818
0
  if (packed->initialized)
819
0
    return;
820
821
0
  prepare_multi_pack_index_one(packed);
822
0
  prepare_packed_git_one(packed);
823
824
0
  sort_packs(&packed->packs.head, sort_pack);
825
0
  for (struct packfile_list_entry *e = packed->packs.head; e; e = e->next)
826
0
    if (!e->next)
827
0
      packed->packs.tail = e;
828
829
0
  packed->initialized = true;
830
0
}
831
832
static void odb_source_packed_reparent(const char *old_cwd,
833
               const char *new_cwd,
834
               void *cb_data)
835
0
{
836
0
  struct odb_source_packed *packed = cb_data;
837
0
  char *path = reparent_relative_path(old_cwd, new_cwd,
838
0
              packed->base.path);
839
0
  free(packed->base.path);
840
0
  packed->base.path = path;
841
0
}
842
843
static void odb_source_packed_close(struct odb_source *source)
844
0
{
845
0
  struct odb_source_packed *packed = odb_source_packed_downcast(source);
846
847
0
  for (struct packfile_list_entry *e = packed->packs.head; e; e = e->next) {
848
0
    if (e->pack->do_not_close)
849
0
      BUG("want to close pack marked 'do-not-close'");
850
0
    close_pack(e->pack);
851
0
  }
852
0
  if (packed->midx)
853
0
    close_midx(packed->midx);
854
0
  packed->midx = NULL;
855
0
}
856
857
static void odb_source_packed_free(struct odb_source *source)
858
0
{
859
0
  struct odb_source_packed *packed = odb_source_packed_downcast(source);
860
861
0
  chdir_notify_unregister(odb_source_packed_reparent, packed);
862
863
0
  odb_source_close(source);
864
0
  for (struct packfile_list_entry *e = packed->packs.head; e; e = e->next)
865
0
    free(e->pack);
866
0
  packfile_list_clear(&packed->packs);
867
868
0
  strmap_clear(&packed->packs_by_path, 0);
869
0
  odb_source_release(&packed->base);
870
0
  free(packed);
871
0
}
872
873
static int verify_packs(struct odb_source_packed *source,
874
      struct odb_fsck_options *opts)
875
0
{
876
0
  struct progress *progress = NULL;
877
0
  struct packfile_list_entry *e;
878
0
  uint32_t total = 0, count = 0;
879
0
  int ret = 0;
880
881
0
  if (opts->flags & ODB_FSCK_PROGRESS) {
882
0
    for (e = packfile_store_get_packs(source); e; e = e->next) {
883
0
      if (open_pack_index(e->pack))
884
0
        continue;
885
0
      total += e->pack->num_objects;
886
0
    }
887
888
0
    progress = start_progress(source->base.odb->repo,
889
0
            _("Checking objects"), total);
890
0
  }
891
892
0
  for (e = packfile_store_get_packs(source); e; e = e->next) {
893
    /* verify gives error messages itself */
894
0
    if (verify_pack(source->base.odb->repo, e->pack,
895
0
        opts->object_cb, opts->object_payload,
896
0
        progress, count))
897
0
      ret = -1;
898
0
    count += e->pack->num_objects;
899
0
  }
900
0
  stop_progress(&progress);
901
902
0
  return ret;
903
0
}
904
905
static int verify_reverse_indices(struct odb_source_packed *source,
906
          struct odb_fsck_options *opts)
907
0
{
908
0
  struct progress *progress = NULL;
909
0
  struct packfile_list_entry *e;
910
0
  uint32_t pack_count = 0;
911
0
  int res = 0;
912
913
0
  if (opts->flags & ODB_FSCK_PROGRESS) {
914
0
    for (e = packfile_store_get_packs(source); e; e = e->next)
915
0
      pack_count++;
916
0
    progress = start_delayed_progress(source->base.odb->repo,
917
0
              "Verifying reverse pack-indexes", pack_count);
918
0
    pack_count = 0;
919
0
  }
920
921
0
  for (e = packfile_store_get_packs(source); e; e = e->next) {
922
0
    int load_error = load_pack_revindex_from_disk(e->pack);
923
924
0
    if (load_error < 0) {
925
0
      error(_("unable to load rev-index for pack '%s'"), e->pack->pack_name);
926
0
      res = -1;
927
0
    } else if (!load_error &&
928
0
         !load_pack_revindex(source->base.odb->repo, e->pack) &&
929
0
         verify_pack_revindex(e->pack)) {
930
0
      error(_("invalid rev-index for pack '%s'"), e->pack->pack_name);
931
0
      res = -1;
932
0
    }
933
0
    display_progress(progress, ++pack_count);
934
0
  }
935
0
  stop_progress(&progress);
936
937
0
  return res;
938
0
}
939
940
static int verify_midx(struct odb_source_packed *source,
941
           struct odb_fsck_options *opts)
942
0
{
943
0
  struct child_process midx_verify = CHILD_PROCESS_INIT;
944
945
0
  prepare_repo_settings(source->base.odb->repo);
946
0
  if (!source->base.odb->repo->settings.core_multi_pack_index)
947
0
    return 0;
948
949
0
  child_process_init(&midx_verify);
950
0
  midx_verify.git_cmd = 1;
951
0
  strvec_pushl(&midx_verify.args, "multi-pack-index",
952
0
         "verify", "--object-dir", source->base.path, NULL);
953
0
  if (opts->flags & ODB_FSCK_PROGRESS)
954
0
    strvec_push(&midx_verify.args, "--progress");
955
0
  else
956
0
    strvec_push(&midx_verify.args, "--no-progress");
957
0
  if (run_command(&midx_verify))
958
0
    return -1;
959
960
0
  return 0;
961
0
}
962
963
static int odb_source_packed_fsck(struct odb_source *source,
964
          struct odb_fsck_options *opts)
965
0
{
966
0
  struct odb_source_packed *packed = odb_source_packed_downcast(source);
967
0
  int ret = 0;
968
969
0
  if ((opts->flags & ODB_FSCK_FULL) && verify_packs(packed, opts) < 0)
970
0
    ret = -1;
971
972
0
  if (verify_reverse_indices(packed, opts) < 0)
973
0
    ret = -1;
974
975
0
  if (verify_bitmap_files(packed))
976
0
    ret = -1;
977
978
0
  if (verify_midx(packed, opts) < 0)
979
0
    ret = -1;
980
981
0
  return ret;
982
0
}
983
984
struct odb_source_packed *odb_source_packed_new(struct object_database *odb,
985
            const char *path,
986
            bool local)
987
0
{
988
0
  struct odb_source_packed *packed;
989
990
0
  CALLOC_ARRAY(packed, 1);
991
0
  odb_source_init(&packed->base, odb, ODB_SOURCE_PACKED, path);
992
0
  strmap_init(&packed->packs_by_path);
993
0
  packed->local = local;
994
995
0
  packed->base.free = odb_source_packed_free;
996
0
  packed->base.close = odb_source_packed_close;
997
0
  packed->base.prepare = odb_source_packed_prepare;
998
0
  packed->base.fsck = odb_source_packed_fsck;
999
0
  packed->base.read_object_info = odb_source_packed_read_object_info;
1000
0
  packed->base.read_object_stream = odb_source_packed_read_object_stream;
1001
0
  packed->base.for_each_object = odb_source_packed_for_each_object;
1002
0
  packed->base.count_objects = odb_source_packed_count_objects;
1003
0
  packed->base.find_abbrev_len = odb_source_packed_find_abbrev_len;
1004
0
  packed->base.freshen_object = odb_source_packed_freshen_object;
1005
0
  packed->base.write_object = odb_source_packed_write_object;
1006
0
  packed->base.write_object_stream = odb_source_packed_write_object_stream;
1007
0
  packed->base.begin_transaction = odb_source_packed_begin_transaction;
1008
1009
0
  if (!is_absolute_path(path))
1010
0
    chdir_notify_register(odb_source_packed_reparent, packed);
1011
1012
0
  return packed;
1013
0
}