Coverage Report

Created: 2026-01-10 06:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/git/odb.c
Line
Count
Source
1
#include "git-compat-util.h"
2
#include "abspath.h"
3
#include "chdir-notify.h"
4
#include "commit-graph.h"
5
#include "config.h"
6
#include "dir.h"
7
#include "environment.h"
8
#include "gettext.h"
9
#include "hex.h"
10
#include "khash.h"
11
#include "lockfile.h"
12
#include "loose.h"
13
#include "midx.h"
14
#include "object-file-convert.h"
15
#include "object-file.h"
16
#include "odb.h"
17
#include "packfile.h"
18
#include "path.h"
19
#include "promisor-remote.h"
20
#include "quote.h"
21
#include "replace-object.h"
22
#include "run-command.h"
23
#include "setup.h"
24
#include "strbuf.h"
25
#include "strvec.h"
26
#include "submodule.h"
27
#include "tmp-objdir.h"
28
#include "trace2.h"
29
#include "write-or-die.h"
30
31
0
KHASH_INIT(odb_path_map, const char * /* key: odb_path */,
32
0
  struct odb_source *, 1, fspathhash, fspatheq)
33
0
34
0
/*
35
0
 * This is meant to hold a *small* number of objects that you would
36
0
 * want odb_read_object() to be able to return, but yet you do not want
37
0
 * to write them into the object store (e.g. a browse-only
38
0
 * application).
39
0
 */
40
0
struct cached_object_entry {
41
0
  struct object_id oid;
42
0
  struct cached_object {
43
0
    enum object_type type;
44
0
    const void *buf;
45
0
    unsigned long size;
46
0
  } value;
47
0
};
48
0
49
0
static const struct cached_object *find_cached_object(struct object_database *object_store,
50
0
                  const struct object_id *oid)
51
0
{
52
0
  static const struct cached_object empty_tree = {
53
0
    .type = OBJ_TREE,
54
0
    .buf = "",
55
0
  };
56
0
  const struct cached_object_entry *co = object_store->cached_objects;
57
58
0
  for (size_t i = 0; i < object_store->cached_object_nr; i++, co++)
59
0
    if (oideq(&co->oid, oid))
60
0
      return &co->value;
61
62
0
  if (oid->algo && oideq(oid, hash_algos[oid->algo].empty_tree))
63
0
    return &empty_tree;
64
65
0
  return NULL;
66
0
}
67
68
int odb_mkstemp(struct object_database *odb,
69
    struct strbuf *temp_filename, const char *pattern)
70
0
{
71
0
  int fd;
72
  /*
73
   * we let the umask do its job, don't try to be more
74
   * restrictive except to remove write permission.
75
   */
76
0
  int mode = 0444;
77
0
  repo_git_path_replace(odb->repo, temp_filename, "objects/%s", pattern);
78
0
  fd = git_mkstemp_mode(temp_filename->buf, mode);
79
0
  if (0 <= fd)
80
0
    return fd;
81
82
  /* slow path */
83
  /* some mkstemp implementations erase temp_filename on failure */
84
0
  repo_git_path_replace(odb->repo, temp_filename, "objects/%s", pattern);
85
0
  safe_create_leading_directories(odb->repo, temp_filename->buf);
86
0
  return xmkstemp_mode(temp_filename->buf, mode);
87
0
}
88
89
/*
90
 * Return non-zero iff the path is usable as an alternate object database.
91
 */
92
static bool odb_is_source_usable(struct object_database *o, const char *path)
93
0
{
94
0
  int r;
95
0
  struct strbuf normalized_objdir = STRBUF_INIT;
96
0
  bool usable = false;
97
98
0
  strbuf_realpath(&normalized_objdir, o->sources->path, 1);
99
100
  /* Detect cases where alternate disappeared */
101
0
  if (!is_directory(path)) {
102
0
    error(_("object directory %s does not exist; "
103
0
      "check .git/objects/info/alternates"),
104
0
          path);
105
0
    goto out;
106
0
  }
107
108
  /*
109
   * Prevent the common mistake of listing the same
110
   * thing twice, or object directory itself.
111
   */
112
0
  if (!o->source_by_path) {
113
0
    khiter_t p;
114
115
0
    o->source_by_path = kh_init_odb_path_map();
116
0
    assert(!o->sources->next);
117
0
    p = kh_put_odb_path_map(o->source_by_path, o->sources->path, &r);
118
0
    assert(r == 1); /* never used */
119
0
    kh_value(o->source_by_path, p) = o->sources;
120
0
  }
121
122
0
  if (fspatheq(path, normalized_objdir.buf))
123
0
    goto out;
124
125
0
  if (kh_get_odb_path_map(o->source_by_path, path) < kh_end(o->source_by_path))
126
0
    goto out;
127
128
0
  usable = true;
129
130
0
out:
131
0
  strbuf_release(&normalized_objdir);
132
0
  return usable;
133
0
}
134
135
static void parse_alternates(const char *string,
136
           int sep,
137
           const char *relative_base,
138
           struct strvec *out)
139
0
{
140
0
  struct strbuf pathbuf = STRBUF_INIT;
141
0
  struct strbuf buf = STRBUF_INIT;
142
143
0
  if (!string || !*string)
144
0
    return;
145
146
0
  while (*string) {
147
0
    const char *end;
148
149
0
    strbuf_reset(&buf);
150
0
    strbuf_reset(&pathbuf);
151
152
0
    if (*string == '#') {
153
      /* comment; consume up to next separator */
154
0
      end = strchrnul(string, sep);
155
0
    } else if (*string == '"' && !unquote_c_style(&buf, string, &end)) {
156
      /*
157
       * quoted path; unquote_c_style has copied the
158
       * data for us and set "end". Broken quoting (e.g.,
159
       * an entry that doesn't end with a quote) falls
160
       * back to the unquoted case below.
161
       */
162
0
    } else {
163
      /* normal, unquoted path */
164
0
      end = strchrnul(string, sep);
165
0
      strbuf_add(&buf, string, end - string);
166
0
    }
167
168
0
    if (*end)
169
0
      end++;
170
0
    string = end;
171
172
0
    if (!buf.len)
173
0
      continue;
174
175
0
    if (!is_absolute_path(buf.buf) && relative_base) {
176
0
      strbuf_realpath(&pathbuf, relative_base, 1);
177
0
      strbuf_addch(&pathbuf, '/');
178
0
    }
179
0
    strbuf_addbuf(&pathbuf, &buf);
180
181
0
    strbuf_reset(&buf);
182
0
    if (!strbuf_realpath(&buf, pathbuf.buf, 0)) {
183
0
      error(_("unable to normalize alternate object path: %s"),
184
0
            pathbuf.buf);
185
0
      continue;
186
0
    }
187
188
    /*
189
     * The trailing slash after the directory name is given by
190
     * this function at the end. Remove duplicates.
191
     */
192
0
    while (buf.len && buf.buf[buf.len - 1] == '/')
193
0
      strbuf_setlen(&buf, buf.len - 1);
194
195
0
    strvec_push(out, buf.buf);
196
0
  }
197
198
0
  strbuf_release(&pathbuf);
199
0
  strbuf_release(&buf);
200
0
}
201
202
static void odb_source_read_alternates(struct odb_source *source,
203
               struct strvec *out)
204
0
{
205
0
  struct strbuf buf = STRBUF_INIT;
206
0
  char *path;
207
208
0
  path = xstrfmt("%s/info/alternates", source->path);
209
0
  if (strbuf_read_file(&buf, path, 1024) < 0) {
210
0
    warn_on_fopen_errors(path);
211
0
    free(path);
212
0
    return;
213
0
  }
214
0
  parse_alternates(buf.buf, '\n', source->path, out);
215
216
0
  strbuf_release(&buf);
217
0
  free(path);
218
0
}
219
220
221
static struct odb_source *odb_source_new(struct object_database *odb,
222
           const char *path,
223
           bool local)
224
0
{
225
0
  struct odb_source *source;
226
227
0
  CALLOC_ARRAY(source, 1);
228
0
  source->odb = odb;
229
0
  source->local = local;
230
0
  source->path = xstrdup(path);
231
0
  source->loose = odb_source_loose_new(source);
232
233
0
  return source;
234
0
}
235
236
static struct odb_source *odb_add_alternate_recursively(struct object_database *odb,
237
              const char *source,
238
              int depth)
239
0
{
240
0
  struct odb_source *alternate = NULL;
241
0
  struct strvec sources = STRVEC_INIT;
242
0
  khiter_t pos;
243
0
  int ret;
244
245
0
  if (!odb_is_source_usable(odb, source))
246
0
    goto error;
247
248
0
  alternate = odb_source_new(odb, source, false);
249
250
  /* add the alternate entry */
251
0
  *odb->sources_tail = alternate;
252
0
  odb->sources_tail = &(alternate->next);
253
254
0
  pos = kh_put_odb_path_map(odb->source_by_path, alternate->path, &ret);
255
0
  if (!ret)
256
0
    BUG("source must not yet exist");
257
0
  kh_value(odb->source_by_path, pos) = alternate;
258
259
  /* recursively add alternates */
260
0
  odb_source_read_alternates(alternate, &sources);
261
0
  if (sources.nr && depth + 1 > 5) {
262
0
    error(_("%s: ignoring alternate object stores, nesting too deep"),
263
0
          source);
264
0
  } else {
265
0
    for (size_t i = 0; i < sources.nr; i++)
266
0
      odb_add_alternate_recursively(odb, sources.v[i], depth + 1);
267
0
  }
268
269
0
 error:
270
0
  strvec_clear(&sources);
271
0
  return alternate;
272
0
}
273
274
static int odb_source_write_alternate(struct odb_source *source,
275
              const char *alternate)
276
0
{
277
0
  struct lock_file lock = LOCK_INIT;
278
0
  char *path = xstrfmt("%s/%s", source->path, "info/alternates");
279
0
  FILE *in, *out;
280
0
  int found = 0;
281
0
  int ret;
282
283
0
  hold_lock_file_for_update(&lock, path, LOCK_DIE_ON_ERROR);
284
0
  out = fdopen_lock_file(&lock, "w");
285
0
  if (!out) {
286
0
    ret = error_errno(_("unable to fdopen alternates lockfile"));
287
0
    goto out;
288
0
  }
289
290
0
  in = fopen(path, "r");
291
0
  if (in) {
292
0
    struct strbuf line = STRBUF_INIT;
293
294
0
    while (strbuf_getline(&line, in) != EOF) {
295
0
      if (!strcmp(alternate, line.buf)) {
296
0
        found = 1;
297
0
        break;
298
0
      }
299
0
      fprintf_or_die(out, "%s\n", line.buf);
300
0
    }
301
302
0
    strbuf_release(&line);
303
0
    fclose(in);
304
0
  } else if (errno != ENOENT) {
305
0
    ret = error_errno(_("unable to read alternates file"));
306
0
    goto out;
307
0
  }
308
309
0
  if (found) {
310
0
    rollback_lock_file(&lock);
311
0
  } else {
312
0
    fprintf_or_die(out, "%s\n", alternate);
313
0
    if (commit_lock_file(&lock)) {
314
0
      ret = error_errno(_("unable to move new alternates file into place"));
315
0
      goto out;
316
0
    }
317
0
  }
318
319
0
  ret = 0;
320
321
0
out:
322
0
  free(path);
323
0
  return ret;
324
0
}
325
326
void odb_add_to_alternates_file(struct object_database *odb,
327
        const char *dir)
328
0
{
329
0
  int ret = odb_source_write_alternate(odb->sources, dir);
330
0
  if (ret < 0)
331
0
    die(NULL);
332
0
  if (odb->loaded_alternates)
333
0
    odb_add_alternate_recursively(odb, dir, 0);
334
0
}
335
336
struct odb_source *odb_add_to_alternates_memory(struct object_database *odb,
337
            const char *dir)
338
0
{
339
  /*
340
   * Make sure alternates are initialized, or else our entry may be
341
   * overwritten when they are.
342
   */
343
0
  odb_prepare_alternates(odb);
344
0
  return odb_add_alternate_recursively(odb, dir, 0);
345
0
}
346
347
struct odb_source *odb_set_temporary_primary_source(struct object_database *odb,
348
                const char *dir, int will_destroy)
349
0
{
350
0
  struct odb_source *source;
351
352
  /*
353
   * Make sure alternates are initialized, or else our entry may be
354
   * overwritten when they are.
355
   */
356
0
  odb_prepare_alternates(odb);
357
358
  /*
359
   * Make a new primary odb and link the old primary ODB in as an
360
   * alternate
361
   */
362
0
  source = odb_source_new(odb, dir, false);
363
364
  /*
365
   * Disable ref updates while a temporary odb is active, since
366
   * the objects in the database may roll back.
367
   */
368
0
  odb->repo->disable_ref_updates = true;
369
0
  source->will_destroy = will_destroy;
370
0
  source->next = odb->sources;
371
0
  odb->sources = source;
372
0
  return source->next;
373
0
}
374
375
static void odb_source_free(struct odb_source *source)
376
0
{
377
0
  free(source->path);
378
0
  odb_source_loose_free(source->loose);
379
0
  free(source);
380
0
}
381
382
void odb_restore_primary_source(struct object_database *odb,
383
        struct odb_source *restore_source,
384
        const char *old_path)
385
0
{
386
0
  struct odb_source *cur_source = odb->sources;
387
388
0
  if (strcmp(old_path, cur_source->path))
389
0
    BUG("expected %s as primary object store; found %s",
390
0
        old_path, cur_source->path);
391
392
0
  if (cur_source->next != restore_source)
393
0
    BUG("we expect the old primary object store to be the first alternate");
394
395
0
  odb->repo->disable_ref_updates = false;
396
0
  odb->sources = restore_source;
397
0
  odb_source_free(cur_source);
398
0
}
399
400
char *compute_alternate_path(const char *path, struct strbuf *err)
401
0
{
402
0
  char *ref_git = NULL;
403
0
  const char *repo;
404
0
  int seen_error = 0;
405
406
0
  ref_git = real_pathdup(path, 0);
407
0
  if (!ref_git) {
408
0
    seen_error = 1;
409
0
    strbuf_addf(err, _("path '%s' does not exist"), path);
410
0
    goto out;
411
0
  }
412
413
0
  repo = read_gitfile(ref_git);
414
0
  if (!repo)
415
0
    repo = read_gitfile(mkpath("%s/.git", ref_git));
416
0
  if (repo) {
417
0
    free(ref_git);
418
0
    ref_git = xstrdup(repo);
419
0
  }
420
421
0
  if (!repo && is_directory(mkpath("%s/.git/objects", ref_git))) {
422
0
    char *ref_git_git = mkpathdup("%s/.git", ref_git);
423
0
    free(ref_git);
424
0
    ref_git = ref_git_git;
425
0
  } else if (!is_directory(mkpath("%s/objects", ref_git))) {
426
0
    struct strbuf sb = STRBUF_INIT;
427
0
    seen_error = 1;
428
0
    if (get_common_dir(&sb, ref_git)) {
429
0
      strbuf_addf(err,
430
0
            _("reference repository '%s' as a linked "
431
0
              "checkout is not supported yet."),
432
0
            path);
433
0
      goto out;
434
0
    }
435
436
0
    strbuf_addf(err, _("reference repository '%s' is not a "
437
0
          "local repository."), path);
438
0
    goto out;
439
0
  }
440
441
0
  if (!access(mkpath("%s/shallow", ref_git), F_OK)) {
442
0
    strbuf_addf(err, _("reference repository '%s' is shallow"),
443
0
          path);
444
0
    seen_error = 1;
445
0
    goto out;
446
0
  }
447
448
0
  if (!access(mkpath("%s/info/grafts", ref_git), F_OK)) {
449
0
    strbuf_addf(err,
450
0
          _("reference repository '%s' is grafted"),
451
0
          path);
452
0
    seen_error = 1;
453
0
    goto out;
454
0
  }
455
456
0
out:
457
0
  if (seen_error) {
458
0
    FREE_AND_NULL(ref_git);
459
0
  }
460
461
0
  return ref_git;
462
0
}
463
464
struct odb_source *odb_find_source(struct object_database *odb, const char *obj_dir)
465
0
{
466
0
  struct odb_source *source;
467
0
  char *obj_dir_real = real_pathdup(obj_dir, 1);
468
0
  struct strbuf odb_path_real = STRBUF_INIT;
469
470
0
  odb_prepare_alternates(odb);
471
0
  for (source = odb->sources; source; source = source->next) {
472
0
    strbuf_realpath(&odb_path_real, source->path, 1);
473
0
    if (!strcmp(obj_dir_real, odb_path_real.buf))
474
0
      break;
475
0
  }
476
477
0
  free(obj_dir_real);
478
0
  strbuf_release(&odb_path_real);
479
480
0
  return source;
481
0
}
482
483
struct odb_source *odb_find_source_or_die(struct object_database *odb, const char *obj_dir)
484
0
{
485
0
  struct odb_source *source = odb_find_source(odb, obj_dir);
486
0
  if (!source)
487
0
    die(_("could not find object directory matching %s"), obj_dir);
488
0
  return source;
489
0
}
490
491
void odb_add_submodule_source_by_path(struct object_database *odb,
492
              const char *path)
493
0
{
494
0
  string_list_insert(&odb->submodule_source_paths, path);
495
0
}
496
497
static void fill_alternate_refs_command(struct repository *repo,
498
          struct child_process *cmd,
499
          const char *repo_path)
500
0
{
501
0
  const char *value;
502
503
0
  if (!repo_config_get_value(repo, "core.alternateRefsCommand", &value)) {
504
0
    cmd->use_shell = 1;
505
506
0
    strvec_push(&cmd->args, value);
507
0
    strvec_push(&cmd->args, repo_path);
508
0
  } else {
509
0
    cmd->git_cmd = 1;
510
511
0
    strvec_pushf(&cmd->args, "--git-dir=%s", repo_path);
512
0
    strvec_push(&cmd->args, "for-each-ref");
513
0
    strvec_push(&cmd->args, "--format=%(objectname)");
514
515
0
    if (!repo_config_get_value(repo, "core.alternateRefsPrefixes", &value)) {
516
0
      strvec_push(&cmd->args, "--");
517
0
      strvec_split(&cmd->args, value);
518
0
    }
519
0
  }
520
521
0
  strvec_pushv(&cmd->env, (const char **)local_repo_env);
522
0
  cmd->out = -1;
523
0
}
524
525
static void read_alternate_refs(struct repository *repo,
526
        const char *path,
527
        odb_for_each_alternate_ref_fn *cb,
528
        void *payload)
529
0
{
530
0
  struct child_process cmd = CHILD_PROCESS_INIT;
531
0
  struct strbuf line = STRBUF_INIT;
532
0
  FILE *fh;
533
534
0
  fill_alternate_refs_command(repo, &cmd, path);
535
536
0
  if (start_command(&cmd))
537
0
    return;
538
539
0
  fh = xfdopen(cmd.out, "r");
540
0
  while (strbuf_getline_lf(&line, fh) != EOF) {
541
0
    struct object_id oid;
542
0
    const char *p;
543
544
0
    if (parse_oid_hex_algop(line.buf, &oid, &p, repo->hash_algo) || *p) {
545
0
      warning(_("invalid line while parsing alternate refs: %s"),
546
0
        line.buf);
547
0
      break;
548
0
    }
549
550
0
    cb(&oid, payload);
551
0
  }
552
553
0
  fclose(fh);
554
0
  finish_command(&cmd);
555
0
  strbuf_release(&line);
556
0
}
557
558
struct alternate_refs_data {
559
  odb_for_each_alternate_ref_fn *fn;
560
  void *payload;
561
};
562
563
static int refs_from_alternate_cb(struct odb_source *alternate,
564
          void *payload)
565
0
{
566
0
  struct strbuf path = STRBUF_INIT;
567
0
  size_t base_len;
568
0
  struct alternate_refs_data *cb = payload;
569
570
0
  if (!strbuf_realpath(&path, alternate->path, 0))
571
0
    goto out;
572
0
  if (!strbuf_strip_suffix(&path, "/objects"))
573
0
    goto out;
574
0
  base_len = path.len;
575
576
  /* Is this a git repository with refs? */
577
0
  strbuf_addstr(&path, "/refs");
578
0
  if (!is_directory(path.buf))
579
0
    goto out;
580
0
  strbuf_setlen(&path, base_len);
581
582
0
  read_alternate_refs(alternate->odb->repo, path.buf, cb->fn, cb->payload);
583
584
0
out:
585
0
  strbuf_release(&path);
586
0
  return 0;
587
0
}
588
589
void odb_for_each_alternate_ref(struct object_database *odb,
590
        odb_for_each_alternate_ref_fn cb, void *payload)
591
0
{
592
0
  struct alternate_refs_data data;
593
0
  data.fn = cb;
594
0
  data.payload = payload;
595
0
  odb_for_each_alternate(odb, refs_from_alternate_cb, &data);
596
0
}
597
598
int odb_for_each_alternate(struct object_database *odb,
599
       odb_for_each_alternate_fn cb, void *payload)
600
0
{
601
0
  struct odb_source *alternate;
602
0
  int r = 0;
603
604
0
  odb_prepare_alternates(odb);
605
0
  for (alternate = odb->sources->next; alternate; alternate = alternate->next) {
606
0
    r = cb(alternate, payload);
607
0
    if (r)
608
0
      break;
609
0
  }
610
0
  return r;
611
0
}
612
613
void odb_prepare_alternates(struct object_database *odb)
614
0
{
615
0
  struct strvec sources = STRVEC_INIT;
616
617
0
  if (odb->loaded_alternates)
618
0
    return;
619
620
0
  parse_alternates(odb->alternate_db, PATH_SEP, NULL, &sources);
621
0
  odb_source_read_alternates(odb->sources, &sources);
622
0
  for (size_t i = 0; i < sources.nr; i++)
623
0
    odb_add_alternate_recursively(odb, sources.v[i], 0);
624
625
0
  odb->loaded_alternates = 1;
626
627
0
  strvec_clear(&sources);
628
0
}
629
630
int odb_has_alternates(struct object_database *odb)
631
0
{
632
0
  odb_prepare_alternates(odb);
633
0
  return !!odb->sources->next;
634
0
}
635
636
int obj_read_use_lock = 0;
637
pthread_mutex_t obj_read_mutex;
638
639
void enable_obj_read_lock(void)
640
0
{
641
0
  if (obj_read_use_lock)
642
0
    return;
643
644
0
  obj_read_use_lock = 1;
645
0
  init_recursive_mutex(&obj_read_mutex);
646
0
}
647
648
void disable_obj_read_lock(void)
649
0
{
650
0
  if (!obj_read_use_lock)
651
0
    return;
652
653
0
  obj_read_use_lock = 0;
654
0
  pthread_mutex_destroy(&obj_read_mutex);
655
0
}
656
657
int fetch_if_missing = 1;
658
659
static int register_all_submodule_sources(struct object_database *odb)
660
0
{
661
0
  int ret = odb->submodule_source_paths.nr;
662
663
0
  for (size_t i = 0; i < odb->submodule_source_paths.nr; i++)
664
0
    odb_add_to_alternates_memory(odb,
665
0
               odb->submodule_source_paths.items[i].string);
666
0
  if (ret) {
667
0
    string_list_clear(&odb->submodule_source_paths, 0);
668
0
    trace2_data_intmax("submodule", odb->repo,
669
0
           "register_all_submodule_sources/registered", ret);
670
0
    if (git_env_bool("GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB", 0))
671
0
      BUG("register_all_submodule_sources() called");
672
0
  }
673
0
  return ret;
674
0
}
675
676
static int do_oid_object_info_extended(struct object_database *odb,
677
               const struct object_id *oid,
678
               struct object_info *oi, unsigned flags)
679
0
{
680
0
  const struct cached_object *co;
681
0
  const struct object_id *real = oid;
682
0
  int already_retried = 0;
683
684
0
  if (flags & OBJECT_INFO_LOOKUP_REPLACE)
685
0
    real = lookup_replace_object(odb->repo, oid);
686
687
0
  if (is_null_oid(real))
688
0
    return -1;
689
690
0
  co = find_cached_object(odb, real);
691
0
  if (co) {
692
0
    if (oi) {
693
0
      if (oi->typep)
694
0
        *(oi->typep) = co->type;
695
0
      if (oi->sizep)
696
0
        *(oi->sizep) = co->size;
697
0
      if (oi->disk_sizep)
698
0
        *(oi->disk_sizep) = 0;
699
0
      if (oi->delta_base_oid)
700
0
        oidclr(oi->delta_base_oid, odb->repo->hash_algo);
701
0
      if (oi->contentp)
702
0
        *oi->contentp = xmemdupz(co->buf, co->size);
703
0
      oi->whence = OI_CACHED;
704
0
    }
705
0
    return 0;
706
0
  }
707
708
0
  odb_prepare_alternates(odb);
709
710
0
  while (1) {
711
0
    struct odb_source *source;
712
713
0
    if (!packfile_store_read_object_info(odb->packfiles, real, oi, flags))
714
0
      return 0;
715
716
    /* Most likely it's a loose object. */
717
0
    for (source = odb->sources; source; source = source->next)
718
0
      if (!odb_source_loose_read_object_info(source, real, oi, flags))
719
0
        return 0;
720
721
    /* Not a loose object; someone else may have just packed it. */
722
0
    if (!(flags & OBJECT_INFO_QUICK)) {
723
0
      odb_reprepare(odb->repo->objects);
724
0
      if (!packfile_store_read_object_info(odb->packfiles, real, oi, flags))
725
0
        return 0;
726
0
    }
727
728
    /*
729
     * This might be an attempt at accessing a submodule object as
730
     * if it were in main object store (having called
731
     * `odb_add_submodule_source_by_path()` on that submodule's
732
     * ODB). If any such ODBs exist, register them and try again.
733
     */
734
0
    if (register_all_submodule_sources(odb))
735
      /* We added some alternates; retry */
736
0
      continue;
737
738
    /* Check if it is a missing object */
739
0
    if (fetch_if_missing && repo_has_promisor_remote(odb->repo) &&
740
0
        !already_retried &&
741
0
        !(flags & OBJECT_INFO_SKIP_FETCH_OBJECT)) {
742
0
      promisor_remote_get_direct(odb->repo, real, 1);
743
0
      already_retried = 1;
744
0
      continue;
745
0
    }
746
747
0
    if (flags & OBJECT_INFO_DIE_IF_CORRUPT) {
748
0
      const struct packed_git *p;
749
0
      if ((flags & OBJECT_INFO_LOOKUP_REPLACE) && !oideq(real, oid))
750
0
        die(_("replacement %s not found for %s"),
751
0
            oid_to_hex(real), oid_to_hex(oid));
752
0
      if ((p = has_packed_and_bad(odb->repo, real)))
753
0
        die(_("packed object %s (stored in %s) is corrupt"),
754
0
            oid_to_hex(real), p->pack_name);
755
0
    }
756
0
    return -1;
757
0
  }
758
0
}
759
760
static int oid_object_info_convert(struct repository *r,
761
           const struct object_id *input_oid,
762
           struct object_info *input_oi, unsigned flags)
763
0
{
764
0
  const struct git_hash_algo *input_algo = &hash_algos[input_oid->algo];
765
0
  int do_die = flags & OBJECT_INFO_DIE_IF_CORRUPT;
766
0
  enum object_type type;
767
0
  struct object_id oid, delta_base_oid;
768
0
  struct object_info new_oi, *oi;
769
0
  unsigned long size;
770
0
  void *content;
771
0
  int ret;
772
773
0
  if (repo_oid_to_algop(r, input_oid, r->hash_algo, &oid)) {
774
0
    if (do_die)
775
0
      die(_("missing mapping of %s to %s"),
776
0
          oid_to_hex(input_oid), r->hash_algo->name);
777
0
    return -1;
778
0
  }
779
780
  /* Is new_oi needed? */
781
0
  oi = input_oi;
782
0
  if (input_oi && (input_oi->delta_base_oid || input_oi->sizep ||
783
0
       input_oi->contentp)) {
784
0
    new_oi = *input_oi;
785
    /* Does delta_base_oid need to be converted? */
786
0
    if (input_oi->delta_base_oid)
787
0
      new_oi.delta_base_oid = &delta_base_oid;
788
    /* Will the attributes differ when converted? */
789
0
    if (input_oi->sizep || input_oi->contentp) {
790
0
      new_oi.contentp = &content;
791
0
      new_oi.sizep = &size;
792
0
      new_oi.typep = &type;
793
0
    }
794
0
    oi = &new_oi;
795
0
  }
796
797
0
  ret = odb_read_object_info_extended(r->objects, &oid, oi, flags);
798
0
  if (ret)
799
0
    return -1;
800
0
  if (oi == input_oi)
801
0
    return ret;
802
803
0
  if (new_oi.contentp) {
804
0
    struct strbuf outbuf = STRBUF_INIT;
805
806
0
    if (type != OBJ_BLOB) {
807
0
      ret = convert_object_file(r, &outbuf,
808
0
              r->hash_algo, input_algo,
809
0
              content, size, type, !do_die);
810
0
      free(content);
811
0
      if (ret == -1)
812
0
        return -1;
813
0
      size = outbuf.len;
814
0
      content = strbuf_detach(&outbuf, NULL);
815
0
    }
816
0
    if (input_oi->sizep)
817
0
      *input_oi->sizep = size;
818
0
    if (input_oi->contentp)
819
0
      *input_oi->contentp = content;
820
0
    else
821
0
      free(content);
822
0
    if (input_oi->typep)
823
0
      *input_oi->typep = type;
824
0
  }
825
0
  if (new_oi.delta_base_oid == &delta_base_oid) {
826
0
    if (repo_oid_to_algop(r, &delta_base_oid, input_algo,
827
0
         input_oi->delta_base_oid)) {
828
0
      if (do_die)
829
0
        die(_("missing mapping of %s to %s"),
830
0
            oid_to_hex(&delta_base_oid),
831
0
            input_algo->name);
832
0
      return -1;
833
0
    }
834
0
  }
835
0
  input_oi->whence = new_oi.whence;
836
0
  input_oi->u = new_oi.u;
837
0
  return ret;
838
0
}
839
840
int odb_read_object_info_extended(struct object_database *odb,
841
          const struct object_id *oid,
842
          struct object_info *oi,
843
          unsigned flags)
844
0
{
845
0
  int ret;
846
847
0
  if (oid->algo && (hash_algo_by_ptr(odb->repo->hash_algo) != oid->algo))
848
0
    return oid_object_info_convert(odb->repo, oid, oi, flags);
849
850
0
  obj_read_lock();
851
0
  ret = do_oid_object_info_extended(odb, oid, oi, flags);
852
0
  obj_read_unlock();
853
0
  return ret;
854
0
}
855
856
857
/* returns enum object_type or negative */
858
int odb_read_object_info(struct object_database *odb,
859
       const struct object_id *oid,
860
       unsigned long *sizep)
861
0
{
862
0
  enum object_type type;
863
0
  struct object_info oi = OBJECT_INFO_INIT;
864
865
0
  oi.typep = &type;
866
0
  oi.sizep = sizep;
867
0
  if (odb_read_object_info_extended(odb, oid, &oi,
868
0
            OBJECT_INFO_LOOKUP_REPLACE) < 0)
869
0
    return -1;
870
0
  return type;
871
0
}
872
873
int odb_pretend_object(struct object_database *odb,
874
           void *buf, unsigned long len, enum object_type type,
875
           struct object_id *oid)
876
0
{
877
0
  struct cached_object_entry *co;
878
0
  char *co_buf;
879
880
0
  hash_object_file(odb->repo->hash_algo, buf, len, type, oid);
881
0
  if (odb_has_object(odb, oid, 0) ||
882
0
      find_cached_object(odb, oid))
883
0
    return 0;
884
885
0
  ALLOC_GROW(odb->cached_objects,
886
0
       odb->cached_object_nr + 1, odb->cached_object_alloc);
887
0
  co = &odb->cached_objects[odb->cached_object_nr++];
888
0
  co->value.size = len;
889
0
  co->value.type = type;
890
0
  co_buf = xmalloc(len);
891
0
  memcpy(co_buf, buf, len);
892
0
  co->value.buf = co_buf;
893
0
  oidcpy(&co->oid, oid);
894
0
  return 0;
895
0
}
896
897
void *odb_read_object(struct object_database *odb,
898
          const struct object_id *oid,
899
          enum object_type *type,
900
          unsigned long *size)
901
0
{
902
0
  struct object_info oi = OBJECT_INFO_INIT;
903
0
  unsigned flags = OBJECT_INFO_DIE_IF_CORRUPT | OBJECT_INFO_LOOKUP_REPLACE;
904
0
  void *data;
905
906
0
  oi.typep = type;
907
0
  oi.sizep = size;
908
0
  oi.contentp = &data;
909
0
  if (odb_read_object_info_extended(odb, oid, &oi, flags))
910
0
    return NULL;
911
912
0
  return data;
913
0
}
914
915
void *odb_read_object_peeled(struct object_database *odb,
916
           const struct object_id *oid,
917
           enum object_type required_type,
918
           unsigned long *size,
919
           struct object_id *actual_oid_return)
920
0
{
921
0
  enum object_type type;
922
0
  void *buffer;
923
0
  unsigned long isize;
924
0
  struct object_id actual_oid;
925
926
0
  oidcpy(&actual_oid, oid);
927
0
  while (1) {
928
0
    int ref_length = -1;
929
0
    const char *ref_type = NULL;
930
931
0
    buffer = odb_read_object(odb, &actual_oid, &type, &isize);
932
0
    if (!buffer)
933
0
      return NULL;
934
0
    if (type == required_type) {
935
0
      *size = isize;
936
0
      if (actual_oid_return)
937
0
        oidcpy(actual_oid_return, &actual_oid);
938
0
      return buffer;
939
0
    }
940
    /* Handle references */
941
0
    else if (type == OBJ_COMMIT)
942
0
      ref_type = "tree ";
943
0
    else if (type == OBJ_TAG)
944
0
      ref_type = "object ";
945
0
    else {
946
0
      free(buffer);
947
0
      return NULL;
948
0
    }
949
0
    ref_length = strlen(ref_type);
950
951
0
    if (ref_length + odb->repo->hash_algo->hexsz > isize ||
952
0
        memcmp(buffer, ref_type, ref_length) ||
953
0
        get_oid_hex_algop((char *) buffer + ref_length, &actual_oid,
954
0
              odb->repo->hash_algo)) {
955
0
      free(buffer);
956
0
      return NULL;
957
0
    }
958
0
    free(buffer);
959
    /* Now we have the ID of the referred-to object in
960
     * actual_oid.  Check again. */
961
0
  }
962
0
}
963
964
int odb_has_object(struct object_database *odb, const struct object_id *oid,
965
         unsigned flags)
966
0
{
967
0
  unsigned object_info_flags = 0;
968
969
0
  if (!startup_info->have_repository)
970
0
    return 0;
971
0
  if (!(flags & HAS_OBJECT_RECHECK_PACKED))
972
0
    object_info_flags |= OBJECT_INFO_QUICK;
973
0
  if (!(flags & HAS_OBJECT_FETCH_PROMISOR))
974
0
    object_info_flags |= OBJECT_INFO_SKIP_FETCH_OBJECT;
975
976
0
  return odb_read_object_info_extended(odb, oid, NULL, object_info_flags) >= 0;
977
0
}
978
979
int odb_freshen_object(struct object_database *odb,
980
           const struct object_id *oid)
981
0
{
982
0
  struct odb_source *source;
983
984
0
  if (packfile_store_freshen_object(odb->packfiles, oid))
985
0
    return 1;
986
987
0
  odb_prepare_alternates(odb);
988
0
  for (source = odb->sources; source; source = source->next)
989
0
    if (odb_source_loose_freshen_object(source, oid))
990
0
      return 1;
991
992
0
  return 0;
993
0
}
994
995
void odb_assert_oid_type(struct object_database *odb,
996
       const struct object_id *oid, enum object_type expect)
997
0
{
998
0
  enum object_type type = odb_read_object_info(odb, oid, NULL);
999
0
  if (type < 0)
1000
0
    die(_("%s is not a valid object"), oid_to_hex(oid));
1001
0
  if (type != expect)
1002
0
    die(_("%s is not a valid '%s' object"), oid_to_hex(oid),
1003
0
        type_name(expect));
1004
0
}
1005
1006
int odb_write_object_ext(struct object_database *odb,
1007
       const void *buf, unsigned long len,
1008
       enum object_type type,
1009
       struct object_id *oid,
1010
       struct object_id *compat_oid,
1011
       unsigned flags)
1012
0
{
1013
0
  return odb_source_loose_write_object(odb->sources, buf, len, type,
1014
0
               oid, compat_oid, flags);
1015
0
}
1016
1017
int odb_write_object_stream(struct object_database *odb,
1018
          struct odb_write_stream *stream, size_t len,
1019
          struct object_id *oid)
1020
0
{
1021
0
  return odb_source_loose_write_stream(odb->sources, stream, len, oid);
1022
0
}
1023
1024
static void odb_update_commondir(const char *name UNUSED,
1025
         const char *old_cwd,
1026
         const char *new_cwd,
1027
         void *cb_data)
1028
0
{
1029
0
  struct object_database *odb = cb_data;
1030
0
  struct tmp_objdir *tmp_objdir;
1031
0
  struct odb_source *source;
1032
1033
0
  tmp_objdir = tmp_objdir_unapply_primary_odb();
1034
1035
  /*
1036
   * In theory, we only have to do this for the primary object source, as
1037
   * alternates' paths are always resolved to an absolute path.
1038
   */
1039
0
  for (source = odb->sources; source; source = source->next) {
1040
0
    char *path;
1041
1042
0
    if (is_absolute_path(source->path))
1043
0
      continue;
1044
1045
0
    path = reparent_relative_path(old_cwd, new_cwd,
1046
0
                source->path);
1047
1048
0
    free(source->path);
1049
0
    source->path = path;
1050
0
  }
1051
1052
0
  if (tmp_objdir)
1053
0
    tmp_objdir_reapply_primary_odb(tmp_objdir, old_cwd, new_cwd);
1054
0
}
1055
1056
struct object_database *odb_new(struct repository *repo,
1057
        const char *primary_source,
1058
        const char *secondary_sources)
1059
0
{
1060
0
  struct object_database *o = xmalloc(sizeof(*o));
1061
0
  char *to_free = NULL;
1062
1063
0
  memset(o, 0, sizeof(*o));
1064
0
  o->repo = repo;
1065
0
  o->packfiles = packfile_store_new(o);
1066
0
  pthread_mutex_init(&o->replace_mutex, NULL);
1067
0
  string_list_init_dup(&o->submodule_source_paths);
1068
1069
0
  if (!primary_source)
1070
0
    primary_source = to_free = xstrfmt("%s/objects", repo->commondir);
1071
0
  o->sources = odb_source_new(o, primary_source, true);
1072
0
  o->sources_tail = &o->sources->next;
1073
0
  o->alternate_db = xstrdup_or_null(secondary_sources);
1074
1075
0
  free(to_free);
1076
1077
0
  chdir_notify_register(NULL, odb_update_commondir, o);
1078
1079
0
  return o;
1080
0
}
1081
1082
void odb_close(struct object_database *o)
1083
0
{
1084
0
  struct odb_source *source;
1085
1086
0
  packfile_store_close(o->packfiles);
1087
1088
0
  for (source = o->sources; source; source = source->next) {
1089
0
    if (source->midx)
1090
0
      close_midx(source->midx);
1091
0
    source->midx = NULL;
1092
0
  }
1093
1094
0
  close_commit_graph(o);
1095
0
}
1096
1097
static void odb_free_sources(struct object_database *o)
1098
0
{
1099
0
  while (o->sources) {
1100
0
    struct odb_source *next;
1101
1102
0
    next = o->sources->next;
1103
0
    odb_source_free(o->sources);
1104
0
    o->sources = next;
1105
0
  }
1106
0
  kh_destroy_odb_path_map(o->source_by_path);
1107
0
  o->source_by_path = NULL;
1108
0
}
1109
1110
void odb_free(struct object_database *o)
1111
60
{
1112
60
  if (!o)
1113
60
    return;
1114
1115
0
  free(o->alternate_db);
1116
1117
0
  oidmap_clear(&o->replace_map, 1);
1118
0
  pthread_mutex_destroy(&o->replace_mutex);
1119
1120
0
  odb_free_sources(o);
1121
1122
0
  for (size_t i = 0; i < o->cached_object_nr; i++)
1123
0
    free((char *) o->cached_objects[i].value.buf);
1124
0
  free(o->cached_objects);
1125
1126
0
  odb_close(o);
1127
0
  packfile_store_free(o->packfiles);
1128
0
  string_list_clear(&o->submodule_source_paths, 0);
1129
1130
0
  chdir_notify_unregister(NULL, odb_update_commondir, o);
1131
1132
0
  free(o);
1133
0
}
1134
1135
void odb_reprepare(struct object_database *o)
1136
0
{
1137
0
  struct odb_source *source;
1138
1139
0
  obj_read_lock();
1140
1141
  /*
1142
   * Reprepare alt odbs, in case the alternates file was modified
1143
   * during the course of this process. This only _adds_ odbs to
1144
   * the linked list, so existing odbs will continue to exist for
1145
   * the lifetime of the process.
1146
   */
1147
0
  o->loaded_alternates = 0;
1148
0
  odb_prepare_alternates(o);
1149
1150
0
  for (source = o->sources; source; source = source->next)
1151
0
    odb_source_loose_reprepare(source);
1152
1153
0
  o->approximate_object_count_valid = 0;
1154
1155
0
  packfile_store_reprepare(o->packfiles);
1156
1157
0
  obj_read_unlock();
1158
0
}
1159
1160
struct odb_transaction *odb_transaction_begin(struct object_database *odb)
1161
0
{
1162
0
  return object_file_transaction_begin(odb->sources);
1163
0
}
1164
1165
void odb_transaction_commit(struct odb_transaction *transaction)
1166
0
{
1167
0
  object_file_transaction_commit(transaction);
1168
0
}