Coverage Report

Created: 2026-11-12 06:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/git/odb/source-files.c
Line
Count
Source
1
#include "git-compat-util.h"
2
#include "abspath.h"
3
#include "blob.h"
4
#include "chdir-notify.h"
5
#include "config.h"
6
#include "gettext.h"
7
#include "hex.h"
8
#include "lockfile.h"
9
#include "object-file.h"
10
#include "odb.h"
11
#include "odb/source.h"
12
#include "odb/source-files.h"
13
#include "odb/source-loose.h"
14
#include "pack-objects.h"
15
#include "packfile.h"
16
#include "path.h"
17
#include "promisor-remote.h"
18
#include "quote.h"
19
#include "repack.h"
20
#include "run-command.h"
21
#include "strbuf.h"
22
#include "string-list.h"
23
#include "strmap.h"
24
#include "strvec.h"
25
#include "tree.h"
26
#include "write-or-die.h"
27
28
struct odb_files_dir *odb_files_dir_new(struct object_database *odb,
29
          const char *path, bool local)
30
0
{
31
0
  struct odb_files_dir *dir;
32
33
0
  CALLOC_ARRAY(dir, 1);
34
0
  dir->abspath = absolute_pathdup(path);
35
0
  dir->local = local;
36
0
  dir->loose = odb_source_loose_new(odb, path);
37
0
  dir->packed = odb_source_packed_new(odb, path, local);
38
39
0
  return dir;
40
0
}
41
42
void odb_files_dir_free(struct odb_files_dir *dir)
43
0
{
44
0
  if (!dir)
45
0
    return;
46
0
  odb_source_free(&dir->loose->base);
47
0
  odb_source_free(&dir->packed->base);
48
0
  free(dir->abspath);
49
0
  free(dir);
50
0
}
51
52
static void odb_source_files_reparent(const char *old_cwd,
53
              const char *new_cwd,
54
              void *cb_data)
55
0
{
56
0
  struct odb_source_files *files = cb_data;
57
0
  char *path = reparent_relative_path(old_cwd, new_cwd,
58
0
              files->base.path);
59
60
0
  free(files->base.path);
61
0
  files->base.path = path;
62
0
}
63
64
static void odb_source_files_free(struct odb_source *source)
65
0
{
66
0
  struct odb_source_files *files = odb_source_files_downcast(source);
67
68
0
  chdir_notify_unregister(odb_source_files_reparent, files);
69
70
0
  while (files->dirs) {
71
0
    struct odb_files_dir *next = files->dirs->next;
72
0
    odb_files_dir_free(files->dirs);
73
0
    files->dirs = next;
74
0
  }
75
0
  strset_clear(&files->dir_paths);
76
0
  stat_validity_clear(&files->alternates_validity);
77
78
0
  odb_source_release(&files->base);
79
0
  free(files);
80
0
}
81
82
static void odb_source_files_close(struct odb_source *source)
83
0
{
84
0
  struct odb_source_files *files = odb_source_files_downcast(source);
85
86
0
  for (struct odb_files_dir *dir = files->dirs; dir; dir = dir->next) {
87
0
    odb_source_close(&dir->loose->base);
88
0
    odb_source_close(&dir->packed->base);
89
0
  }
90
0
}
91
92
static int odb_source_files_create_on_disk(struct odb_source *source,
93
             const struct odb_create_on_disk_options *opts)
94
0
{
95
0
  struct lock_file alternates_lock = LOCK_INIT;
96
0
  struct strbuf path = STRBUF_INIT;
97
0
  struct strset seen = STRSET_INIT;
98
0
  struct strbuf line = STRBUF_INIT;
99
0
  int ret;
100
101
0
  safe_create_dir(source->odb->repo, source->path, 1);
102
103
0
  strbuf_addf(&path, "%s/pack", source->path);
104
0
  safe_create_dir(source->odb->repo, path.buf, 1);
105
106
0
  strbuf_reset(&path);
107
0
  strbuf_addf(&path, "%s/info", source->path);
108
0
  safe_create_dir(source->odb->repo, path.buf, 1);
109
110
0
  if (opts->alternates && opts->alternates->nr) {
111
0
    FILE *alternates, *orig;
112
113
0
    strbuf_reset(&path);
114
0
    strbuf_addf(&path, "%s/info/alternates", source->path);
115
116
0
    repo_hold_lock_file_for_update(source->odb->repo, &alternates_lock,
117
0
                 path.buf, LOCK_DIE_ON_ERROR);
118
119
0
    alternates = fdopen_lock_file(&alternates_lock, "w");
120
0
    if (!alternates) {
121
0
      ret = error_errno(_("unable to fdopen alternates lockfile"));
122
0
      goto out;
123
0
    }
124
125
    /*
126
     * The alternates file may already exist, e.g. when it has been
127
     * seeded from a template directory. Read any preexisting
128
     * entries so that we don't end up writing duplicates.
129
     */
130
0
    orig = fopen(path.buf, "r");
131
0
    if (orig) {
132
0
      while (strbuf_getline(&line, orig) != EOF) {
133
0
        strset_add(&seen, line.buf);
134
0
        fprintf(alternates, "%s\n", line.buf);
135
0
      }
136
137
0
      if (ferror(orig)) {
138
0
        ret = error_errno(_("unable to read alternates file"));
139
0
        fclose(orig);
140
0
        goto out;
141
0
      }
142
143
0
      fclose(orig);
144
0
    } else if (errno != ENOENT) {
145
0
      ret = error_errno(_("unable to read alternates file"));
146
0
      goto out;
147
0
    }
148
149
0
    for (size_t i = 0; i < opts->alternates->nr; i++) {
150
0
      const char *alternate = opts->alternates->v[i];
151
0
      if (!strset_add(&seen, alternate))
152
0
        continue;
153
0
      fprintf(alternates, "%s\n", alternate);
154
0
    }
155
156
0
    if (ferror(alternates)) {
157
0
      ret = error_errno(_("unable to write alternates file"));
158
0
      goto out;
159
0
    }
160
161
0
    if (commit_lock_file(&alternates_lock)) {
162
0
      ret = error_errno(_("unable to commit alternates file"));
163
0
      goto out;
164
0
    }
165
0
  }
166
167
  /* Reprepare the object database to activate alternates. */
168
0
  odb_reprepare(source->odb);
169
170
0
  ret = 0;
171
172
0
out:
173
0
  rollback_lock_file(&alternates_lock);
174
0
  strbuf_release(&line);
175
0
  strbuf_release(&path);
176
0
  strset_clear(&seen);
177
0
  return ret;
178
0
}
179
180
/*
181
 * Return non-zero iff the path is usable as an alternate object directory.
182
 */
183
static bool odb_files_dir_is_usable(struct odb_source_files *files,
184
            const char *path)
185
0
{
186
0
  struct strbuf buf = STRBUF_INIT;
187
0
  bool usable = false;
188
189
  /*
190
   * Prevent the common mistake of listing the same thing twice,
191
   * or object directory itself.
192
   *
193
   * NEEDSWORK: we're using "core.ignoreCase" to deduplicate
194
   * alternates that _may_ be the same. This requires quite a bit
195
   * of boilerplate for dubious benefit:
196
   *
197
   *   - Duplicating alternates should really only lead to
198
   *     regressed performance.
199
   *
200
   *   - We don't properly resolve symlinks or mointpoints, so we
201
   *     may still end up duplicating alternates.
202
   *
203
   *   - The value may be lying, in which case we might
204
   *     deduplicate alternates that are in fact not mapping to the
205
   *     same directory.
206
   *
207
   * We should investigate whether we can remove this whole
208
   * mechanism outright.
209
   */
210
0
  if (strset_empty(&files->dir_paths)) {
211
0
    files->dir_paths_icase = 0;
212
0
    repo_config_get_bool(files->base.odb->repo, "core.ignorecase",
213
0
             &files->dir_paths_icase);
214
215
0
    strbuf_realpath(&buf, files->base.path, 1);
216
0
    if (files->dir_paths_icase)
217
0
      strbuf_tolower(&buf);
218
0
    strset_add(&files->dir_paths, buf.buf);
219
220
0
    for (struct odb_files_dir *dir = files->dirs; dir; dir = dir->next) {
221
0
      strbuf_reset(&buf);
222
0
      strbuf_addstr(&buf, dir->abspath);
223
0
      if (files->dir_paths_icase)
224
0
        strbuf_tolower(&buf);
225
0
      strset_add(&files->dir_paths, buf.buf);
226
0
    }
227
0
  }
228
229
0
  strbuf_reset(&buf);
230
0
  strbuf_addstr(&buf, path);
231
0
  if (files->dir_paths_icase)
232
0
    strbuf_tolower(&buf);
233
234
0
  if (strset_contains(&files->dir_paths, buf.buf))
235
0
    goto out;
236
237
  /* Detect cases where alternate disappeared */
238
0
  if (!is_directory(path)) {
239
0
    error(_("object directory %s does not exist; "
240
0
      "check .git/objects/info/alternates"),
241
0
          path);
242
0
    goto out;
243
0
  }
244
245
0
  usable = true;
246
247
0
out:
248
0
  strbuf_release(&buf);
249
0
  return usable;
250
0
}
251
252
static void parse_alternates(const char *string,
253
           int sep,
254
           const char *relative_base,
255
           struct strvec *out)
256
0
{
257
0
  struct strbuf pathbuf = STRBUF_INIT;
258
0
  struct strbuf buf = STRBUF_INIT;
259
260
0
  if (!string || !*string)
261
0
    return;
262
263
0
  while (*string) {
264
0
    const char *end;
265
266
0
    strbuf_reset(&buf);
267
0
    strbuf_reset(&pathbuf);
268
269
0
    if (*string == '#') {
270
      /* comment; consume up to next separator */
271
0
      end = strchrnul(string, sep);
272
0
    } else if (*string == '"' && !unquote_c_style(&buf, string, &end)) {
273
      /*
274
       * quoted path; unquote_c_style has copied the
275
       * data for us and set "end". Broken quoting (e.g.,
276
       * an entry that doesn't end with a quote) falls
277
       * back to the unquoted case below.
278
       */
279
0
    } else {
280
      /* normal, unquoted path */
281
0
      end = strchrnul(string, sep);
282
0
      strbuf_add(&buf, string, end - string);
283
0
    }
284
285
0
    if (*end)
286
0
      end++;
287
0
    string = end;
288
289
0
    if (!buf.len)
290
0
      continue;
291
292
0
    if (!is_absolute_path(buf.buf) && relative_base) {
293
0
      strbuf_realpath(&pathbuf, relative_base, 1);
294
0
      strbuf_addch(&pathbuf, '/');
295
0
    }
296
0
    strbuf_addbuf(&pathbuf, &buf);
297
298
0
    strbuf_reset(&buf);
299
0
    if (!strbuf_realpath(&buf, pathbuf.buf, 0)) {
300
0
      error(_("unable to normalize alternate object path: %s"),
301
0
            pathbuf.buf);
302
0
      continue;
303
0
    }
304
305
    /*
306
     * The trailing slash after the directory name is given by
307
     * this function at the end. Remove duplicates.
308
     */
309
0
    while (buf.len && buf.buf[buf.len - 1] == '/')
310
0
      strbuf_setlen(&buf, buf.len - 1);
311
312
0
    strvec_push(out, buf.buf);
313
0
  }
314
315
0
  strbuf_release(&pathbuf);
316
0
  strbuf_release(&buf);
317
0
}
318
319
static void read_alternates(const char *object_dir, struct strvec *out,
320
          struct stat_validity *validity)
321
0
{
322
0
  struct strbuf buf = STRBUF_INIT;
323
0
  char *path;
324
325
0
  path = xstrfmt("%s/info/alternates", object_dir);
326
0
  if (!validity || !stat_validity_check(validity, path)) {
327
0
    bool successful = false;
328
0
    int fd;
329
330
0
    fd = open(path, O_RDONLY);
331
0
    if (fd < 0) {
332
0
      warn_on_fopen_errors(path);
333
0
    } else {
334
0
      if (validity)
335
0
        stat_validity_update(validity, fd);
336
0
      if (strbuf_read(&buf, fd, 1024) < 0) {
337
0
        warning_errno(_("unable to read alternates file '%s'"),
338
0
                path);
339
0
      } else {
340
0
        parse_alternates(buf.buf, '\n', object_dir, out);
341
0
        successful = true;
342
0
      }
343
0
    }
344
345
0
    if (validity && !successful)
346
0
      stat_validity_clear(validity);
347
0
    if (fd >= 0)
348
0
      close(fd);
349
0
  }
350
351
0
  strbuf_release(&buf);
352
0
  free(path);
353
0
}
354
355
static void add_alternate_recursively(struct odb_source_files *files,
356
              const char *path,
357
              int depth)
358
0
{
359
0
  struct odb_files_dir *alternate;
360
0
  struct strvec alternates = STRVEC_INIT;
361
362
0
  if (!odb_files_dir_is_usable(files, path))
363
0
    goto out;
364
365
0
  alternate = odb_files_dir_new(files->base.odb, path, false);
366
367
  /* add the alternate entry */
368
0
  *files->dirs_tail = alternate;
369
0
  files->dirs_tail = &(alternate->next);
370
371
0
  if (files->dir_paths_icase) {
372
0
    struct strbuf path = STRBUF_INIT;
373
374
0
    strbuf_addstr(&path, alternate->abspath);
375
0
    strbuf_tolower(&path);
376
0
    strset_add(&files->dir_paths, path.buf);
377
378
0
    strbuf_release(&path);
379
0
  } else {
380
0
    strset_add(&files->dir_paths, alternate->abspath);
381
0
  }
382
383
  /* recursively add alternates */
384
0
  read_alternates(alternate->abspath, &alternates, NULL);
385
0
  if (alternates.nr && depth + 1 > 5) {
386
0
    error(_("%s: ignoring alternate object stores, nesting too deep"),
387
0
          path);
388
0
  } else {
389
0
    for (size_t i = 0; i < alternates.nr; i++)
390
0
      add_alternate_recursively(files, alternates.v[i], depth + 1);
391
0
  }
392
393
0
 out:
394
0
  strvec_clear(&alternates);
395
0
}
396
397
static void prepare_alternates(struct odb_source_files *files,
398
             const char *alternate_db)
399
0
{
400
0
  struct strvec alternates = STRVEC_INIT;
401
402
0
  parse_alternates(alternate_db, PATH_SEP, NULL, &alternates);
403
0
  read_alternates(files->base.path, &alternates,
404
0
      &files->alternates_validity);
405
406
0
  for (size_t i = 0; i < alternates.nr; i++)
407
0
    add_alternate_recursively(files, alternates.v[i], 0);
408
409
0
  strvec_clear(&alternates);
410
0
}
411
412
static void odb_source_files_prepare(struct odb_source *source,
413
             enum odb_prepare_flags flags)
414
0
{
415
0
  struct odb_source_files *files = odb_source_files_downcast(source);
416
417
  /*
418
   * Reprepare alternates, in case the alternates file was modified
419
   * during the course of this process. This only _adds_ directories to
420
   * the linked list, so existing directories will continue to exist
421
   * for the lifetime of the process.
422
   */
423
0
  if (flags & ODB_PREPARE_FLUSH_CACHES)
424
0
    prepare_alternates(files, NULL);
425
426
0
  for (struct odb_files_dir *dir = files->dirs; dir; dir = dir->next) {
427
0
    odb_source_prepare(&dir->loose->base, flags);
428
0
    odb_source_prepare(&dir->packed->base, flags);
429
0
  }
430
0
}
431
432
static enum odb_read_status odb_source_files_read_object_info(struct odb_source *source,
433
                    const struct object_id *oid,
434
                    struct object_info *oi,
435
                    enum object_info_flags flags,
436
                    struct strbuf *errmsg)
437
0
{
438
0
  struct odb_source_files *files = odb_source_files_downcast(source);
439
0
  struct odb_files_dir **tail = NULL;
440
0
  enum odb_read_status status = ODB_READ_NOT_FOUND;
441
0
  enum odb_read_status ret;
442
0
  bool retry = false;
443
444
0
retry:
445
  /*
446
   * Reading an object may fail even though the object exists, for
447
   * example because it is corrupt. Report this failure to the caller in
448
   * case none of the directories was able to read the object, and
449
   * prefer the first such error in case multiple reads have failed.
450
   */
451
0
  for (struct odb_files_dir *dir = files->dirs; dir; dir = dir->next) {
452
0
    if (retry)
453
0
      odb_source_prepare(&dir->packed->base, ODB_PREPARE_FLUSH_CACHES);
454
455
0
    ret = odb_source_read_object_info(&dir->packed->base, oid, oi, flags,
456
0
              status == ODB_READ_NOT_FOUND ? errmsg : NULL);
457
0
    if (!ret)
458
0
      return 0;
459
0
    if (ret != ODB_READ_NOT_FOUND && status == ODB_READ_NOT_FOUND)
460
0
      status = ret;
461
0
  }
462
463
  /*
464
   * When we have reprepared alternates then we only re-scan directories
465
   * that were newly added.
466
   */
467
0
  for (struct odb_files_dir *dir = tail ? *tail : files->dirs; dir; dir = dir->next) {
468
0
    ret = odb_source_read_object_info(&dir->loose->base, oid, oi, flags,
469
0
              status == ODB_READ_NOT_FOUND ? errmsg : NULL);
470
0
    if (!ret)
471
0
      return 0;
472
0
    if (ret != ODB_READ_NOT_FOUND && status == ODB_READ_NOT_FOUND)
473
0
      status = ret;
474
0
  }
475
476
0
  if (!retry && !(flags & OBJECT_INFO_QUICK)) {
477
0
    tail = files->dirs_tail;
478
0
    prepare_alternates(files, NULL);
479
0
    retry = true;
480
0
    goto retry;
481
0
  }
482
483
0
  return status;
484
0
}
485
486
static int odb_source_files_read_object_stream(struct odb_stream **out,
487
                 struct odb_source *source,
488
                 const struct object_id *oid)
489
0
{
490
0
  struct odb_source_files *files = odb_source_files_downcast(source);
491
492
0
  for (struct odb_files_dir *dir = files->dirs; dir; dir = dir->next)
493
0
    if (!odb_source_read_object_stream(out, &dir->packed->base, oid))
494
0
      return 0;
495
0
  for (struct odb_files_dir *dir = files->dirs; dir; dir = dir->next)
496
0
    if (!odb_source_read_object_stream(out, &dir->loose->base, oid))
497
0
      return 0;
498
499
0
  return -1;
500
0
}
501
502
static int odb_source_files_for_each_object(struct odb_source *source,
503
              const struct object_info *request,
504
              odb_for_each_object_cb cb,
505
              void *cb_data,
506
              const struct odb_for_each_object_options *opts)
507
0
{
508
0
  struct odb_source_files *files = odb_source_files_downcast(source);
509
0
  int ret;
510
511
0
  for (struct odb_files_dir *dir = files->dirs; dir; dir = dir->next) {
512
0
    if (opts->flags & ODB_FOR_EACH_OBJECT_LOCAL_ONLY && !dir->local)
513
0
      continue;
514
515
0
    if (!(opts->flags & ODB_FOR_EACH_OBJECT_PROMISOR_ONLY)) {
516
0
      ret = odb_source_for_each_object(&dir->loose->base, request, cb, cb_data, opts);
517
0
      if (ret)
518
0
        return ret;
519
0
    }
520
521
0
    ret = odb_source_for_each_object(&dir->packed->base, request, cb, cb_data, opts);
522
0
    if (ret)
523
0
      return ret;
524
0
  }
525
526
0
  return 0;
527
0
}
528
529
static int odb_source_files_count_objects(struct odb_source *source,
530
            enum odb_count_objects_flags flags,
531
            unsigned long *out)
532
0
{
533
0
  struct odb_source_files *files = odb_source_files_downcast(source);
534
0
  unsigned long count = 0;
535
0
  int ret;
536
537
0
  for (struct odb_files_dir *dir = files->dirs; dir; dir = dir->next) {
538
0
    unsigned long dir_count;
539
540
0
    ret = odb_source_count_objects(&dir->packed->base, flags, &dir_count);
541
0
    if (ret < 0)
542
0
      goto out;
543
0
    count += dir_count;
544
545
0
    if (!(flags & ODB_COUNT_OBJECTS_APPROXIMATE)) {
546
0
      ret = odb_source_count_objects(&dir->loose->base, flags, &dir_count);
547
0
      if (ret < 0)
548
0
        goto out;
549
0
      count += dir_count;
550
0
    }
551
0
  }
552
553
0
  *out = count;
554
0
  ret = 0;
555
556
0
out:
557
0
  return ret;
558
0
}
559
560
static int odb_source_files_find_abbrev_len(struct odb_source *source,
561
              const struct object_id *oid,
562
              unsigned min_len,
563
              unsigned *out)
564
0
{
565
0
  struct odb_source_files *files = odb_source_files_downcast(source);
566
0
  unsigned len = min_len;
567
0
  int ret = 0;
568
569
0
  for (struct odb_files_dir *dir = files->dirs; dir; dir = dir->next) {
570
0
    ret = odb_source_find_abbrev_len(&dir->packed->base, oid, len, &len);
571
0
    if (ret < 0)
572
0
      goto out;
573
574
0
    ret = odb_source_find_abbrev_len(&dir->loose->base, oid, len, &len);
575
0
    if (ret < 0)
576
0
      goto out;
577
0
  }
578
579
0
  *out = len;
580
0
  ret = 0;
581
582
0
out:
583
0
  return ret;
584
0
}
585
586
static int odb_source_files_freshen_object(struct odb_source *source,
587
             const struct object_id *oid,
588
             const time_t *mtime)
589
0
{
590
0
  struct odb_source_files *files = odb_source_files_downcast(source);
591
592
0
  for (struct odb_files_dir *dir = files->dirs; dir; dir = dir->next)
593
0
    if (odb_source_freshen_object(&dir->packed->base, oid, mtime) ||
594
0
        odb_source_freshen_object(&dir->loose->base, oid, mtime))
595
0
      return 1;
596
597
0
  return 0;
598
0
}
599
600
static int odb_source_files_write_object(struct odb_source *source,
601
           const void *buf, size_t len,
602
           enum object_type type,
603
           const struct object_id *oid,
604
           const struct object_id *compat_oid,
605
           const time_t *mtime,
606
           enum odb_write_object_flags flags)
607
0
{
608
0
  struct odb_source_files *files = odb_source_files_downcast(source);
609
0
  return odb_source_write_object(&files->dirs->loose->base, buf, len, type,
610
0
               oid, compat_oid, mtime, flags);
611
0
}
612
613
static int odb_source_files_write_object_stream(struct odb_source *source,
614
            struct odb_stream *stream,
615
            struct object_id *oid)
616
0
{
617
0
  struct odb_source_files *files = odb_source_files_downcast(source);
618
0
  return odb_source_write_object_stream(&files->dirs->loose->base, stream, oid);
619
0
}
620
621
static int odb_source_files_begin_transaction(struct odb_source *source,
622
                struct odb_transaction **out,
623
                enum odb_transaction_flags flags)
624
0
{
625
0
  return odb_transaction_files_begin(source, out, flags);
626
0
}
627
628
static int too_many_loose_objects(struct odb_source_files *files, int limit)
629
0
{
630
0
  unsigned long loose_count;
631
632
0
  if (limit <= 0)
633
0
    return 0;
634
635
0
  if (odb_source_count_objects(&files->dirs->loose->base, ODB_COUNT_OBJECTS_APPROXIMATE,
636
0
             &loose_count) < 0)
637
0
    return 0;
638
639
  /*
640
   * This is weird, but stems from legacy behaviour: the GC auto
641
   * threshold was always essentially interpreted as if it was rounded up
642
   * to the next multiple 256 of, so we retain this behaviour for now.
643
   */
644
0
  return loose_count > (DIV_ROUND_UP(((unsigned long) limit), 256) * 256);
645
0
}
646
647
static struct packed_git *find_base_packs(struct odb_source_files *files,
648
            struct string_list *packs,
649
            unsigned long limit)
650
0
{
651
0
  struct packfile_list_entry *e;
652
0
  struct packed_git *base = NULL;
653
654
0
  for (e = packfile_store_get_packs(files->dirs->packed); e; e = e->next) {
655
0
    if (e->pack->is_cruft)
656
0
      continue;
657
0
    if (limit) {
658
0
      if ((uintmax_t) e->pack->pack_size >= limit)
659
0
        string_list_append(packs, e->pack->pack_name);
660
0
    } else if (!base || base->pack_size < e->pack->pack_size) {
661
0
      base = e->pack;
662
0
    }
663
0
  }
664
665
0
  if (base)
666
0
    string_list_append(packs, base->pack_name);
667
668
0
  return base;
669
0
}
670
671
static int too_many_packs(struct odb_source_files *files, int gc_auto_pack_limit)
672
0
{
673
0
  struct packfile_list_entry *e;
674
0
  int cnt = 0;
675
676
0
  if (gc_auto_pack_limit <= 0)
677
0
    return 0;
678
679
0
  for (e = packfile_store_get_packs(files->dirs->packed); e; e = e->next) {
680
0
    if (e->pack->pack_keep)
681
0
      continue;
682
    /*
683
     * Perhaps check the size of the pack and count only
684
     * very small ones here?
685
     */
686
0
    cnt++;
687
0
  }
688
0
  return gc_auto_pack_limit < cnt;
689
0
}
690
691
static uint64_t total_ram(void)
692
0
{
693
0
#if defined(HAVE_SYSINFO)
694
0
  struct sysinfo si;
695
696
0
  if (!sysinfo(&si)) {
697
0
    uint64_t total = si.totalram;
698
699
0
    if (si.mem_unit > 1)
700
0
      total *= (uint64_t)si.mem_unit;
701
0
    return total;
702
0
  }
703
#elif defined(HAVE_BSD_SYSCTL) && (defined(HW_MEMSIZE) || defined(HW_PHYSMEM) || defined(HW_PHYSMEM64))
704
  uint64_t physical_memory;
705
  int mib[2];
706
  size_t length;
707
708
  mib[0] = CTL_HW;
709
# if defined(HW_MEMSIZE)
710
  mib[1] = HW_MEMSIZE;
711
# elif defined(HW_PHYSMEM64)
712
  mib[1] = HW_PHYSMEM64;
713
# else
714
  mib[1] = HW_PHYSMEM;
715
# endif
716
  length = sizeof(physical_memory);
717
  if (!sysctl(mib, 2, &physical_memory, &length, NULL, 0)) {
718
    if (length == 4) {
719
      uint32_t mem;
720
721
      if (!sysctl(mib, 2, &mem, &length, NULL, 0))
722
        physical_memory = mem;
723
    }
724
    return physical_memory;
725
  }
726
#elif defined(GIT_WINDOWS_NATIVE)
727
  MEMORYSTATUSEX memInfo;
728
729
  memInfo.dwLength = sizeof(MEMORYSTATUSEX);
730
  if (GlobalMemoryStatusEx(&memInfo))
731
    return memInfo.ullTotalPhys;
732
#endif
733
0
  return 0;
734
0
}
735
736
static uint64_t estimate_repack_memory(struct odb_source_files *files,
737
               struct packed_git *pack)
738
0
{
739
0
  unsigned long max_delta_cache_size = DEFAULT_DELTA_CACHE_SIZE;
740
0
  unsigned long delta_base_cache_limit = DEFAULT_DELTA_BASE_CACHE_LIMIT;
741
0
  unsigned long nr_objects;
742
0
  size_t os_cache, heap;
743
744
0
  if (odb_source_count_objects(&files->base, ODB_COUNT_OBJECTS_APPROXIMATE,
745
0
             &nr_objects) < 0)
746
0
    return 0;
747
748
0
  if (!pack || !nr_objects)
749
0
    return 0;
750
751
0
  repo_config_get_ulong(files->base.odb->repo, "pack.deltacachesize",
752
0
            &max_delta_cache_size);
753
0
  repo_config_get_ulong(files->base.odb->repo, "core.deltabasecachelimit",
754
0
            &delta_base_cache_limit);
755
756
  /*
757
   * First we have to scan through at least one pack.
758
   * Assume enough room in OS file cache to keep the entire pack
759
   * or we may accidentally evict data of other processes from
760
   * the cache.
761
   */
762
0
  os_cache = pack->pack_size + pack->index_size;
763
  /* then pack-objects needs lots more for book keeping */
764
0
  heap = sizeof(struct object_entry) * nr_objects;
765
  /*
766
   * internal rev-list --all --objects takes up some memory too,
767
   * let's say half of it is for blobs
768
   */
769
0
  heap += sizeof(struct blob) * nr_objects / 2;
770
  /*
771
   * and the other half is for trees (commits and tags are
772
   * usually insignificant)
773
   */
774
0
  heap += sizeof(struct tree) * nr_objects / 2;
775
  /* and then obj_hash[], underestimated in fact */
776
0
  heap += sizeof(struct object *) * nr_objects;
777
  /* revindex is used also */
778
0
  heap += (sizeof(off_t) + sizeof(uint32_t)) * nr_objects;
779
  /*
780
   * read_sha1_file() (either at delta calculation phase, or
781
   * writing phase) also fills up the delta base cache
782
   */
783
0
  heap += delta_base_cache_limit;
784
  /* and of course pack-objects has its own delta cache */
785
0
  heap += max_delta_cache_size;
786
787
0
  return os_cache + heap;
788
0
}
789
790
static int keep_one_pack(struct string_list_item *item, void *data)
791
0
{
792
0
  struct strvec *args = data;
793
0
  strvec_pushf(args, "--keep-pack=%s", basename(item->string));
794
0
  return 0;
795
0
}
796
797
static void add_repack_all_option(struct repository *repo,
798
          const struct odb_optimize_options *opts,
799
          struct string_list *keep_pack,
800
          struct strvec *args)
801
0
{
802
0
  char *repack_filter = NULL;
803
0
  char *repack_filter_to = NULL;
804
805
0
  repo_config_get_string(repo, "gc.repackfilter", &repack_filter);
806
0
  repo_config_get_string(repo, "gc.repackfilterto", &repack_filter_to);
807
808
0
  if (opts->prune_expire && !strcmp(opts->prune_expire, "now") &&
809
0
      !(opts->cruft_packs && opts->expire_to))
810
0
    strvec_push(args, "-a");
811
0
  else if (opts->cruft_packs) {
812
0
    strvec_push(args, "--cruft");
813
0
    if (opts->prune_expire)
814
0
      strvec_pushf(args, "--cruft-expiration=%s", opts->prune_expire);
815
0
    if (opts->max_cruft_size)
816
0
      strvec_pushf(args, "--max-cruft-size=%lu",
817
0
             opts->max_cruft_size);
818
0
    if (opts->expire_to)
819
0
      strvec_pushf(args, "--expire-to=%s", opts->expire_to);
820
0
  } else {
821
0
    strvec_push(args, "-A");
822
0
    if (opts->prune_expire)
823
0
      strvec_pushf(args, "--unpack-unreachable=%s", opts->prune_expire);
824
0
  }
825
826
0
  if (keep_pack)
827
0
    for_each_string_list(keep_pack, keep_one_pack, args);
828
829
0
  if (repack_filter && *repack_filter)
830
0
    strvec_pushf(args, "--filter=%s", repack_filter);
831
0
  if (repack_filter_to && *repack_filter_to)
832
0
    strvec_pushf(args, "--filter-to=%s", repack_filter_to);
833
834
0
  free(repack_filter);
835
0
  free(repack_filter_to);
836
0
}
837
838
static void add_repack_incremental_option(struct strvec *args)
839
0
{
840
0
  strvec_push(args, "--no-write-bitmap-index");
841
0
}
842
843
bool odb_source_files_optimize_required(struct odb_source *source,
844
          const struct odb_optimize_options *opts)
845
0
{
846
0
  struct odb_source_files *files = odb_source_files_downcast(source);
847
0
  struct repository *repo = source->odb->repo;
848
849
0
  switch (opts->strategy) {
850
0
  case ODB_OPTIMIZE_INCREMENTAL: {
851
0
    int gc_auto_threshold = 6700;
852
0
    int gc_auto_pack_limit = 50;
853
854
0
    repo_config_get_int(repo, "gc.auto", &gc_auto_threshold);
855
0
    repo_config_get_int(repo, "gc.autopacklimit", &gc_auto_pack_limit);
856
857
    /*
858
     * Setting gc.auto to 0 or negative can disable the
859
     * automatic gc.
860
     */
861
0
    if (gc_auto_threshold <= 0)
862
0
      return false;
863
0
    if (!too_many_packs(files, gc_auto_pack_limit) &&
864
0
        !too_many_loose_objects(files, gc_auto_threshold))
865
0
      return false;
866
867
0
    return true;
868
0
  }
869
0
  case ODB_OPTIMIZE_GEOMETRIC: {
870
0
    struct pack_geometry geometry = {
871
0
      .split_factor = 2,
872
0
    };
873
0
    struct pack_objects_args po_args = {
874
0
      .local = 1,
875
0
    };
876
0
    struct existing_packs existing_packs = EXISTING_PACKS_INIT;
877
0
    struct string_list kept_packs = STRING_LIST_INIT_DUP;
878
0
    int auto_value = 6700;
879
0
    bool ret;
880
881
0
    repo_config_get_int(repo, "maintenance.geometric-repack.auto",
882
0
            &auto_value);
883
0
    if (!auto_value)
884
0
      return false;
885
0
    if (auto_value < 0)
886
0
      return true;
887
888
0
    repo_config_get_int(repo, "maintenance.geometric-repack.splitFactor",
889
0
            &geometry.split_factor);
890
891
0
    existing_packs.repo = repo;
892
0
    existing_packs_collect(&existing_packs, &kept_packs);
893
0
    pack_geometry_init(&geometry, &existing_packs, &po_args);
894
0
    pack_geometry_split(&geometry);
895
896
    /*
897
     * When we'd merge at least two packs with one another we always
898
     * perform the repack.
899
     */
900
0
    if (geometry.split) {
901
0
      ret = true;
902
0
      goto out;
903
0
    }
904
905
    /*
906
     * Otherwise, we estimate the number of loose objects to determine
907
     * whether we want to create a new packfile or not.
908
     */
909
0
    if (too_many_loose_objects(files, auto_value)) {
910
0
      ret = true;
911
0
      goto out;
912
0
    }
913
914
0
    ret = false;
915
916
0
  out:
917
0
    existing_packs_release(&existing_packs);
918
0
    pack_geometry_release(&geometry);
919
0
    return ret;
920
0
  }
921
0
  default:
922
0
    BUG("unknown maintenance strategy '%d'", opts->strategy);
923
0
  }
924
0
}
925
926
int odb_source_files_optimize(struct odb_source *source,
927
            const struct odb_optimize_options *opts)
928
0
{
929
0
  struct odb_source_files *files = odb_source_files_downcast(source);
930
0
  struct repository *repo = source->odb->repo;
931
0
  struct child_process repack_cmd = CHILD_PROCESS_INIT;
932
0
  unsigned long big_pack_threshold = 0;
933
0
  int gc_auto_threshold = 6700;
934
0
  int gc_auto_pack_limit = 50;
935
0
  int ret;
936
937
0
  repo_config_get_int(repo, "gc.auto", &gc_auto_threshold);
938
0
  repo_config_get_int(repo, "gc.autopacklimit", &gc_auto_pack_limit);
939
0
  repo_config_get_ulong(repo, "gc.bigpackthreshold", &big_pack_threshold);
940
941
0
  if (repo->repository_format_precious_objects)
942
0
    return 0;
943
944
0
  repack_cmd.git_cmd = 1;
945
0
  repack_cmd.odb_to_close = repo->objects;
946
947
0
  strvec_pushl(&repack_cmd.args, "repack", "-d", "-l", NULL);
948
0
  if (opts->flags & ODB_OPTIMIZE_NO_REUSE_DELTAS)
949
0
    strvec_push(&repack_cmd.args, "-f");
950
0
  if (opts->depth > 0)
951
0
    strvec_pushf(&repack_cmd.args, "--depth=%d", opts->depth);
952
0
  if (opts->window > 0)
953
0
    strvec_pushf(&repack_cmd.args, "--window=%d", opts->window);
954
0
  if (!(opts->flags & ODB_OPTIMIZE_VERBOSE))
955
0
    strvec_push(&repack_cmd.args, "-q");
956
957
  /*
958
   * There's three cases we need to consider:
959
   *
960
   *   - If we're invoked without `--auto` we'll need to perform a full
961
   *     repack.
962
   *
963
   *   - If we're invoked with `--auto` and there's too many packs, then
964
   *     we perform a full repack, as well.
965
   *
966
   *   - Otherwise we perform an incremental repack.
967
   */
968
0
  switch (opts->strategy) {
969
0
  case ODB_OPTIMIZE_INCREMENTAL:
970
0
    if (!(opts->flags & ODB_OPTIMIZE_AUTO)) {
971
0
      struct string_list keep_pack = STRING_LIST_INIT_NODUP;
972
973
0
      if (opts->keep_largest_pack != -1) {
974
0
        if (opts->keep_largest_pack)
975
0
          find_base_packs(files, &keep_pack, 0);
976
0
      } else if (big_pack_threshold) {
977
0
        find_base_packs(files, &keep_pack, big_pack_threshold);
978
0
      }
979
980
0
      add_repack_all_option(repo, opts, &keep_pack, &repack_cmd.args);
981
0
      string_list_clear(&keep_pack, 0);
982
0
    } else {
983
0
      if (too_many_packs(files, gc_auto_pack_limit)) {
984
0
        struct string_list keep_pack = STRING_LIST_INIT_NODUP;
985
986
0
        if (big_pack_threshold) {
987
0
          find_base_packs(files, &keep_pack, big_pack_threshold);
988
0
          if (keep_pack.nr >= (unsigned long) gc_auto_pack_limit) {
989
0
            string_list_clear(&keep_pack, 0);
990
0
            find_base_packs(files, &keep_pack, 0);
991
0
          }
992
0
        } else {
993
0
          struct packed_git *p = find_base_packs(files, &keep_pack, 0);
994
0
          uint64_t mem_have, mem_want;
995
996
0
          mem_have = total_ram();
997
0
          mem_want = estimate_repack_memory(files, p);
998
999
          /*
1000
           * Only allow 1/2 of memory for pack-objects, leave
1001
           * the rest for the OS and other processes in the
1002
           * system.
1003
           */
1004
0
          if (!mem_have || mem_want < mem_have / 2)
1005
0
            string_list_clear(&keep_pack, 0);
1006
0
        }
1007
1008
0
        add_repack_all_option(repo, opts, &keep_pack, &repack_cmd.args);
1009
0
        string_list_clear(&keep_pack, 0);
1010
0
      } else {
1011
0
        add_repack_incremental_option(&repack_cmd.args);
1012
0
      }
1013
0
    }
1014
1015
0
    break;
1016
0
  case ODB_OPTIMIZE_GEOMETRIC: {
1017
0
    struct pack_geometry geometry = {
1018
0
      .split_factor = 2,
1019
0
    };
1020
0
    struct pack_objects_args po_args = {
1021
0
      .local = 1,
1022
0
    };
1023
0
    struct existing_packs existing_packs = EXISTING_PACKS_INIT;
1024
0
    struct string_list kept_packs = STRING_LIST_INIT_DUP;
1025
1026
0
    repo_config_get_int(repo, "maintenance.geometric-repack.splitFactor",
1027
0
            &geometry.split_factor);
1028
1029
0
    existing_packs.repo = repo;
1030
0
    existing_packs_collect(&existing_packs, &kept_packs);
1031
0
    pack_geometry_init(&geometry, &existing_packs, &po_args);
1032
0
    pack_geometry_split(&geometry);
1033
1034
0
    if (geometry.split < geometry.pack_nr) {
1035
0
      strvec_pushf(&repack_cmd.args, "--geometric=%d",
1036
0
             geometry.split_factor);
1037
0
    } else {
1038
0
      add_repack_all_option(repo, opts, NULL, &repack_cmd.args);
1039
0
    }
1040
0
    if (repo->settings.core_multi_pack_index)
1041
0
      strvec_push(&repack_cmd.args, "--write-midx");
1042
1043
0
    existing_packs_release(&existing_packs);
1044
0
    pack_geometry_release(&geometry);
1045
0
    break;
1046
0
  }
1047
0
  default:
1048
0
    die("unknown maintenance strategy '%d'", opts->strategy);
1049
0
  }
1050
1051
0
  if (run_command(&repack_cmd)) {
1052
0
    ret = error("failed to run %s", repack_cmd.args.v[0]);
1053
0
    goto out;
1054
0
  }
1055
1056
  /* Geometric repacking uses cruft packs, so we don't have to prune separately. */
1057
0
  if (opts->strategy != ODB_OPTIMIZE_GEOMETRIC && opts->prune_expire) {
1058
0
    struct child_process prune_cmd = CHILD_PROCESS_INIT;
1059
1060
0
    strvec_pushl(&prune_cmd.args, "prune", "--expire", NULL);
1061
    /* run `git prune` even if using cruft packs */
1062
0
    strvec_push(&prune_cmd.args, opts->prune_expire);
1063
0
    if (!(opts->flags & ODB_OPTIMIZE_VERBOSE))
1064
0
      strvec_push(&prune_cmd.args, "--no-progress");
1065
0
    if (repo_has_promisor_remote(repo))
1066
0
      strvec_push(&prune_cmd.args,
1067
0
            "--exclude-promisor-objects");
1068
0
    prune_cmd.git_cmd = 1;
1069
1070
0
    if (run_command(&prune_cmd)) {
1071
0
      ret = error("failed to run %s", prune_cmd.args.v[0]);
1072
0
      goto out;
1073
0
    }
1074
0
  }
1075
1076
0
  if (opts->flags & ODB_OPTIMIZE_AUTO && too_many_loose_objects(files, gc_auto_threshold))
1077
0
    warning(_("There are too many unreachable loose objects; "
1078
0
      "run 'git prune' to remove them."));
1079
1080
0
  ret = 0;
1081
1082
0
out:
1083
0
  return ret;
1084
0
}
1085
1086
struct odb_pack_generator_files {
1087
  struct odb_pack_generator base;
1088
  struct child_process cp;
1089
};
1090
1091
static int odb_pack_generator_files_finish(struct odb_pack_generator *_generator)
1092
0
{
1093
0
  struct odb_pack_generator_files *generator =
1094
0
    (struct odb_pack_generator_files *)_generator;
1095
0
  int ret;
1096
1097
0
  ret = finish_command(&generator->cp);
1098
0
  free(generator);
1099
1100
0
  if (ret) {
1101
    /*
1102
     * On failure, pack-objects is expected to have written a
1103
     * useful error message to its standard error stream already.
1104
     * Death by signal is worth mentioning, though, with the
1105
     * exception of SIGPIPE: that is a normal occurrence when the
1106
     * consumer of the pack hangs up.
1107
     */
1108
0
    if (ret > 128 && ret - 128 == SIGPIPE)
1109
0
      return -1;
1110
0
    if (ret > 128)
1111
0
      error(_("pack-objects died of signal %d"), ret - 128);
1112
0
    return -1;
1113
0
  }
1114
1115
0
  return 0;
1116
0
}
1117
1118
static int odb_source_files_generate_pack(struct odb_source *source UNUSED,
1119
            struct odb_pack_generator **out,
1120
            const struct odb_generate_pack_options *opts)
1121
0
{
1122
0
  struct odb_pack_generator_files *generator;
1123
0
  struct child_process *cp;
1124
0
  FILE *in;
1125
1126
0
  CALLOC_ARRAY(generator, 1);
1127
0
  child_process_init(&generator->cp);
1128
0
  cp = &generator->cp;
1129
1130
  /*
1131
   * The hook is expected to spawn "$hook git pack-objects <args...>"
1132
   * and to behave like git-pack-objects(1) would have. This can for
1133
   * example be used to serve precomputed packfiles.
1134
   */
1135
0
  if (opts->pack_objects_hook) {
1136
0
    strvec_push(&cp->args, opts->pack_objects_hook);
1137
0
    strvec_push(&cp->args, "git");
1138
0
    cp->use_shell = 1;
1139
0
  } else {
1140
0
    cp->git_cmd = 1;
1141
0
  }
1142
1143
  /*
1144
   * The caller-provided shallow boundary overrides any shallow state
1145
   * that the repository itself may have, so the shallow file needs to
1146
   * be neutralized.
1147
   */
1148
0
  if (opts->shallows.nr) {
1149
0
    strvec_push(&cp->args, "--shallow-file");
1150
0
    strvec_push(&cp->args, "");
1151
0
  }
1152
0
  strvec_push(&cp->args, "pack-objects");
1153
0
  strvec_push(&cp->args, "--revs");
1154
0
  strvec_push(&cp->args, "--stdout");
1155
0
  if (opts->thin)
1156
0
    strvec_push(&cp->args, "--thin");
1157
0
  if (opts->shallow)
1158
0
    strvec_push(&cp->args, "--shallow");
1159
0
  if (opts->ofs_delta)
1160
0
    strvec_push(&cp->args, "--delta-base-offset");
1161
0
  if (opts->include_tag)
1162
0
    strvec_push(&cp->args, "--include-tag");
1163
0
  if (opts->missing_allow_promisor)
1164
0
    strvec_push(&cp->args, "--missing=allow-promisor");
1165
0
  if (opts->disable_bitmaps)
1166
0
    strvec_push(&cp->args, "--no-use-bitmap-index");
1167
0
  switch (opts->progress) {
1168
0
  case ODB_GENERATE_PACK_PROGRESS_NONE:
1169
0
    strvec_push(&cp->args, "--quiet");
1170
0
    break;
1171
0
  case ODB_GENERATE_PACK_PROGRESS_STANDARD:
1172
0
    strvec_push(&cp->args, "--progress");
1173
0
    break;
1174
0
  case ODB_GENERATE_PACK_PROGRESS_VERBOSE:
1175
0
    strvec_push(&cp->args, "--all-progress");
1176
0
    break;
1177
0
  default:
1178
0
    BUG("unknown progress option %d", opts->progress);
1179
0
  }
1180
0
  if (opts->filter_spec)
1181
0
    strvec_pushf(&cp->args, "--filter=%s", opts->filter_spec);
1182
0
  if (opts->uri_protocols)
1183
0
    for (size_t i = 0; i < opts->uri_protocols->nr; i++)
1184
0
      strvec_pushf(&cp->args, "--uri-protocol=%s",
1185
0
             opts->uri_protocols->items[i].string);
1186
1187
0
  cp->in = -1;
1188
0
  cp->out = opts->pack_fd;
1189
0
  cp->err = opts->progress_fd;
1190
0
  cp->clean_on_exit = 1;
1191
1192
0
  if (start_command(cp)) {
1193
0
    free(generator);
1194
0
    return error(_("could not spawn pack-objects"));
1195
0
  }
1196
1197
  /*
1198
   * Feed the objects to pack-objects. This is safe to do synchronously
1199
   * because pack-objects consumes all of its standard input before it
1200
   * starts to generate the pack.
1201
   */
1202
0
  in = xfdopen(cp->in, "w");
1203
0
  for (size_t i = 0; i < opts->shallows.nr; i++)
1204
0
    fprintf(in, "--shallow %s\n", oid_to_hex(&opts->shallows.oid[i]));
1205
0
  for (size_t i = 0; i < opts->wants.nr; i++)
1206
0
    fprintf(in, "%s\n", oid_to_hex(&opts->wants.oid[i]));
1207
0
  fprintf(in, "--not\n");
1208
0
  for (size_t i = 0; i < opts->haves.nr; i++)
1209
0
    fprintf(in, "%s\n", oid_to_hex(&opts->haves.oid[i]));
1210
0
  fprintf(in, "\n");
1211
0
  fflush(in);
1212
0
  if (ferror(in)) {
1213
0
    error(_("error writing to pack-objects"));
1214
0
    fclose(in);
1215
0
    if (opts->pack_fd < 0)
1216
0
      close(cp->out);
1217
0
    if (opts->progress_fd < 0)
1218
0
      close(cp->err);
1219
0
    finish_command(cp);
1220
0
    free(generator);
1221
0
    return -1;
1222
0
  }
1223
0
  fclose(in);
1224
1225
0
  generator->base.out = opts->pack_fd < 0 ? cp->out : -1;
1226
0
  generator->base.err = opts->progress_fd < 0 ? cp->err : -1;
1227
0
  generator->base.finish = odb_pack_generator_files_finish;
1228
1229
0
  *out = &generator->base;
1230
0
  return 0;
1231
0
}
1232
1233
static int odb_source_files_fsck(struct odb_source *source,
1234
         struct odb_fsck_options *opts)
1235
0
{
1236
0
  struct odb_source_files *files = odb_source_files_downcast(source);
1237
0
  int ret = 0;
1238
1239
0
  for (struct odb_files_dir *dir = files->dirs; dir; dir = dir->next) {
1240
0
    if (!(opts->flags & ODB_FSCK_FULL) && !dir->local)
1241
0
      continue;
1242
1243
0
    ret |= odb_source_fsck(&dir->loose->base, opts);
1244
0
    ret |= odb_source_fsck(&dir->packed->base, opts);
1245
0
  }
1246
1247
0
  return ret;
1248
0
}
1249
1250
struct odb_files_dir *odb_source_files_find_dir(struct object_database *odb, const char *obj_dir)
1251
0
{
1252
0
  struct odb_source_files *files = odb_source_files_downcast(odb->source);
1253
0
  char *obj_dir_real = real_pathdup(obj_dir, 1);
1254
0
  struct strbuf odb_path_real = STRBUF_INIT;
1255
0
  struct odb_files_dir *dir;
1256
1257
0
  for (dir = files->dirs; dir; dir = dir->next) {
1258
0
    strbuf_realpath(&odb_path_real, dir->abspath, 1);
1259
0
    if (!strcmp(obj_dir_real, odb_path_real.buf))
1260
0
      break;
1261
0
  }
1262
1263
0
  free(obj_dir_real);
1264
0
  strbuf_release(&odb_path_real);
1265
0
  return dir;
1266
0
}
1267
1268
struct odb_source_files *odb_source_files_new(struct object_database *odb,
1269
                const char *payload,
1270
                enum odb_new_flags flags)
1271
0
{
1272
0
  struct odb_source_files *files;
1273
0
  char *object_dir = NULL;
1274
0
  char *alternates = NULL;
1275
1276
0
  if (flags & ODB_NEW_HONOR_ENV) {
1277
0
    object_dir = xstrdup_or_null(getenv(DB_ENVIRONMENT));
1278
0
    alternates = xstrdup_or_null(getenv(ALTERNATE_DB_ENVIRONMENT));
1279
0
  }
1280
0
  if (!object_dir && payload) {
1281
0
    if (is_absolute_path(payload))
1282
0
      object_dir = xstrdup(payload);
1283
0
    else
1284
0
      object_dir = xstrfmt("%s/%s", odb->repo->commondir, payload);
1285
0
  }
1286
0
  if (!object_dir)
1287
0
    object_dir = xstrfmt("%s/objects", odb->repo->commondir);
1288
1289
0
  CALLOC_ARRAY(files, 1);
1290
0
  odb_source_init(&files->base, odb, ODB_SOURCE_FILES, object_dir);
1291
1292
0
  files->dirs = odb_files_dir_new(odb, object_dir, true);
1293
0
  files->dirs_tail = &files->dirs->next;
1294
0
  strset_init(&files->dir_paths);
1295
1296
0
  files->base.free = odb_source_files_free;
1297
0
  files->base.close = odb_source_files_close;
1298
0
  files->base.create_on_disk = odb_source_files_create_on_disk;
1299
0
  files->base.prepare = odb_source_files_prepare;
1300
0
  files->base.fsck = odb_source_files_fsck;
1301
0
  files->base.read_object_info = odb_source_files_read_object_info;
1302
0
  files->base.read_object_stream = odb_source_files_read_object_stream;
1303
0
  files->base.for_each_object = odb_source_files_for_each_object;
1304
0
  files->base.count_objects = odb_source_files_count_objects;
1305
0
  files->base.find_abbrev_len = odb_source_files_find_abbrev_len;
1306
0
  files->base.freshen_object = odb_source_files_freshen_object;
1307
0
  files->base.write_object = odb_source_files_write_object;
1308
0
  files->base.write_object_stream = odb_source_files_write_object_stream;
1309
0
  files->base.begin_transaction = odb_source_files_begin_transaction;
1310
0
  files->base.optimize = odb_source_files_optimize;
1311
0
  files->base.optimize_required = odb_source_files_optimize_required;
1312
0
  files->base.generate_pack = odb_source_files_generate_pack;
1313
1314
  /*
1315
   * Ideally, we would only ever store absolute paths in the source. This
1316
   * is not (yet) possible though because we access and assume relative
1317
   * paths in the primary ODB source in some user-facing functionality.
1318
   */
1319
0
  if (!is_absolute_path(object_dir))
1320
0
    chdir_notify_register(odb_source_files_reparent, files);
1321
1322
0
  prepare_alternates(files, alternates);
1323
1324
0
  free(object_dir);
1325
0
  free(alternates);
1326
0
  return files;
1327
0
}