Coverage Report

Created: 2026-02-26 06:44

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
0
  source->packfiles = packfile_store_new(source);
233
234
0
  return source;
235
0
}
236
237
static struct odb_source *odb_add_alternate_recursively(struct object_database *odb,
238
              const char *source,
239
              int depth)
240
0
{
241
0
  struct odb_source *alternate = NULL;
242
0
  struct strvec sources = STRVEC_INIT;
243
0
  khiter_t pos;
244
0
  int ret;
245
246
0
  if (!odb_is_source_usable(odb, source))
247
0
    goto error;
248
249
0
  alternate = odb_source_new(odb, source, false);
250
251
  /* add the alternate entry */
252
0
  *odb->sources_tail = alternate;
253
0
  odb->sources_tail = &(alternate->next);
254
255
0
  pos = kh_put_odb_path_map(odb->source_by_path, alternate->path, &ret);
256
0
  if (!ret)
257
0
    BUG("source must not yet exist");
258
0
  kh_value(odb->source_by_path, pos) = alternate;
259
260
  /* recursively add alternates */
261
0
  odb_source_read_alternates(alternate, &sources);
262
0
  if (sources.nr && depth + 1 > 5) {
263
0
    error(_("%s: ignoring alternate object stores, nesting too deep"),
264
0
          source);
265
0
  } else {
266
0
    for (size_t i = 0; i < sources.nr; i++)
267
0
      odb_add_alternate_recursively(odb, sources.v[i], depth + 1);
268
0
  }
269
270
0
 error:
271
0
  strvec_clear(&sources);
272
0
  return alternate;
273
0
}
274
275
static int odb_source_write_alternate(struct odb_source *source,
276
              const char *alternate)
277
0
{
278
0
  struct lock_file lock = LOCK_INIT;
279
0
  char *path = xstrfmt("%s/%s", source->path, "info/alternates");
280
0
  FILE *in, *out;
281
0
  int found = 0;
282
0
  int ret;
283
284
0
  hold_lock_file_for_update(&lock, path, LOCK_DIE_ON_ERROR);
285
0
  out = fdopen_lock_file(&lock, "w");
286
0
  if (!out) {
287
0
    ret = error_errno(_("unable to fdopen alternates lockfile"));
288
0
    goto out;
289
0
  }
290
291
0
  in = fopen(path, "r");
292
0
  if (in) {
293
0
    struct strbuf line = STRBUF_INIT;
294
295
0
    while (strbuf_getline(&line, in) != EOF) {
296
0
      if (!strcmp(alternate, line.buf)) {
297
0
        found = 1;
298
0
        break;
299
0
      }
300
0
      fprintf_or_die(out, "%s\n", line.buf);
301
0
    }
302
303
0
    strbuf_release(&line);
304
0
    fclose(in);
305
0
  } else if (errno != ENOENT) {
306
0
    ret = error_errno(_("unable to read alternates file"));
307
0
    goto out;
308
0
  }
309
310
0
  if (found) {
311
0
    rollback_lock_file(&lock);
312
0
  } else {
313
0
    fprintf_or_die(out, "%s\n", alternate);
314
0
    if (commit_lock_file(&lock)) {
315
0
      ret = error_errno(_("unable to move new alternates file into place"));
316
0
      goto out;
317
0
    }
318
0
  }
319
320
0
  ret = 0;
321
322
0
out:
323
0
  free(path);
324
0
  return ret;
325
0
}
326
327
void odb_add_to_alternates_file(struct object_database *odb,
328
        const char *dir)
329
0
{
330
0
  int ret = odb_source_write_alternate(odb->sources, dir);
331
0
  if (ret < 0)
332
0
    die(NULL);
333
0
  if (odb->loaded_alternates)
334
0
    odb_add_alternate_recursively(odb, dir, 0);
335
0
}
336
337
struct odb_source *odb_add_to_alternates_memory(struct object_database *odb,
338
            const char *dir)
339
0
{
340
  /*
341
   * Make sure alternates are initialized, or else our entry may be
342
   * overwritten when they are.
343
   */
344
0
  odb_prepare_alternates(odb);
345
0
  return odb_add_alternate_recursively(odb, dir, 0);
346
0
}
347
348
struct odb_source *odb_set_temporary_primary_source(struct object_database *odb,
349
                const char *dir, int will_destroy)
350
0
{
351
0
  struct odb_source *source;
352
353
  /*
354
   * Make sure alternates are initialized, or else our entry may be
355
   * overwritten when they are.
356
   */
357
0
  odb_prepare_alternates(odb);
358
359
  /*
360
   * Make a new primary odb and link the old primary ODB in as an
361
   * alternate
362
   */
363
0
  source = odb_source_new(odb, dir, false);
364
365
  /*
366
   * Disable ref updates while a temporary odb is active, since
367
   * the objects in the database may roll back.
368
   */
369
0
  odb->repo->disable_ref_updates = true;
370
0
  source->will_destroy = will_destroy;
371
0
  source->next = odb->sources;
372
0
  odb->sources = source;
373
0
  return source->next;
374
0
}
375
376
static void odb_source_free(struct odb_source *source)
377
0
{
378
0
  free(source->path);
379
0
  odb_source_loose_free(source->loose);
380
0
  packfile_store_free(source->packfiles);
381
0
  free(source);
382
0
}
383
384
void odb_restore_primary_source(struct object_database *odb,
385
        struct odb_source *restore_source,
386
        const char *old_path)
387
0
{
388
0
  struct odb_source *cur_source = odb->sources;
389
390
0
  if (strcmp(old_path, cur_source->path))
391
0
    BUG("expected %s as primary object store; found %s",
392
0
        old_path, cur_source->path);
393
394
0
  if (cur_source->next != restore_source)
395
0
    BUG("we expect the old primary object store to be the first alternate");
396
397
0
  odb->repo->disable_ref_updates = false;
398
0
  odb->sources = restore_source;
399
0
  odb_source_free(cur_source);
400
0
}
401
402
char *compute_alternate_path(const char *path, struct strbuf *err)
403
0
{
404
0
  char *ref_git = NULL;
405
0
  const char *repo;
406
0
  int seen_error = 0;
407
408
0
  ref_git = real_pathdup(path, 0);
409
0
  if (!ref_git) {
410
0
    seen_error = 1;
411
0
    strbuf_addf(err, _("path '%s' does not exist"), path);
412
0
    goto out;
413
0
  }
414
415
0
  repo = read_gitfile(ref_git);
416
0
  if (!repo)
417
0
    repo = read_gitfile(mkpath("%s/.git", ref_git));
418
0
  if (repo) {
419
0
    free(ref_git);
420
0
    ref_git = xstrdup(repo);
421
0
  }
422
423
0
  if (!repo && is_directory(mkpath("%s/.git/objects", ref_git))) {
424
0
    char *ref_git_git = mkpathdup("%s/.git", ref_git);
425
0
    free(ref_git);
426
0
    ref_git = ref_git_git;
427
0
  } else if (!is_directory(mkpath("%s/objects", ref_git))) {
428
0
    struct strbuf sb = STRBUF_INIT;
429
0
    seen_error = 1;
430
0
    if (get_common_dir(&sb, ref_git)) {
431
0
      strbuf_addf(err,
432
0
            _("reference repository '%s' as a linked "
433
0
              "checkout is not supported yet."),
434
0
            path);
435
0
      goto out;
436
0
    }
437
438
0
    strbuf_addf(err, _("reference repository '%s' is not a "
439
0
          "local repository."), path);
440
0
    goto out;
441
0
  }
442
443
0
  if (!access(mkpath("%s/shallow", ref_git), F_OK)) {
444
0
    strbuf_addf(err, _("reference repository '%s' is shallow"),
445
0
          path);
446
0
    seen_error = 1;
447
0
    goto out;
448
0
  }
449
450
0
  if (!access(mkpath("%s/info/grafts", ref_git), F_OK)) {
451
0
    strbuf_addf(err,
452
0
          _("reference repository '%s' is grafted"),
453
0
          path);
454
0
    seen_error = 1;
455
0
    goto out;
456
0
  }
457
458
0
out:
459
0
  if (seen_error) {
460
0
    FREE_AND_NULL(ref_git);
461
0
  }
462
463
0
  return ref_git;
464
0
}
465
466
struct odb_source *odb_find_source(struct object_database *odb, const char *obj_dir)
467
0
{
468
0
  struct odb_source *source;
469
0
  char *obj_dir_real = real_pathdup(obj_dir, 1);
470
0
  struct strbuf odb_path_real = STRBUF_INIT;
471
472
0
  odb_prepare_alternates(odb);
473
0
  for (source = odb->sources; source; source = source->next) {
474
0
    strbuf_realpath(&odb_path_real, source->path, 1);
475
0
    if (!strcmp(obj_dir_real, odb_path_real.buf))
476
0
      break;
477
0
  }
478
479
0
  free(obj_dir_real);
480
0
  strbuf_release(&odb_path_real);
481
482
0
  return source;
483
0
}
484
485
struct odb_source *odb_find_source_or_die(struct object_database *odb, const char *obj_dir)
486
0
{
487
0
  struct odb_source *source = odb_find_source(odb, obj_dir);
488
0
  if (!source)
489
0
    die(_("could not find object directory matching %s"), obj_dir);
490
0
  return source;
491
0
}
492
493
void odb_add_submodule_source_by_path(struct object_database *odb,
494
              const char *path)
495
0
{
496
0
  string_list_insert(&odb->submodule_source_paths, path);
497
0
}
498
499
static void fill_alternate_refs_command(struct repository *repo,
500
          struct child_process *cmd,
501
          const char *repo_path)
502
0
{
503
0
  const char *value;
504
505
0
  if (!repo_config_get_value(repo, "core.alternateRefsCommand", &value)) {
506
0
    cmd->use_shell = 1;
507
508
0
    strvec_push(&cmd->args, value);
509
0
    strvec_push(&cmd->args, repo_path);
510
0
  } else {
511
0
    cmd->git_cmd = 1;
512
513
0
    strvec_pushf(&cmd->args, "--git-dir=%s", repo_path);
514
0
    strvec_push(&cmd->args, "for-each-ref");
515
0
    strvec_push(&cmd->args, "--format=%(objectname)");
516
517
0
    if (!repo_config_get_value(repo, "core.alternateRefsPrefixes", &value)) {
518
0
      strvec_push(&cmd->args, "--");
519
0
      strvec_split(&cmd->args, value);
520
0
    }
521
0
  }
522
523
0
  strvec_pushv(&cmd->env, (const char **)local_repo_env);
524
0
  cmd->out = -1;
525
0
}
526
527
static void read_alternate_refs(struct repository *repo,
528
        const char *path,
529
        odb_for_each_alternate_ref_fn *cb,
530
        void *payload)
531
0
{
532
0
  struct child_process cmd = CHILD_PROCESS_INIT;
533
0
  struct strbuf line = STRBUF_INIT;
534
0
  FILE *fh;
535
536
0
  fill_alternate_refs_command(repo, &cmd, path);
537
538
0
  if (start_command(&cmd))
539
0
    return;
540
541
0
  fh = xfdopen(cmd.out, "r");
542
0
  while (strbuf_getline_lf(&line, fh) != EOF) {
543
0
    struct object_id oid;
544
0
    const char *p;
545
546
0
    if (parse_oid_hex_algop(line.buf, &oid, &p, repo->hash_algo) || *p) {
547
0
      warning(_("invalid line while parsing alternate refs: %s"),
548
0
        line.buf);
549
0
      break;
550
0
    }
551
552
0
    cb(&oid, payload);
553
0
  }
554
555
0
  fclose(fh);
556
0
  finish_command(&cmd);
557
0
  strbuf_release(&line);
558
0
}
559
560
struct alternate_refs_data {
561
  odb_for_each_alternate_ref_fn *fn;
562
  void *payload;
563
};
564
565
static int refs_from_alternate_cb(struct odb_source *alternate,
566
          void *payload)
567
0
{
568
0
  struct strbuf path = STRBUF_INIT;
569
0
  size_t base_len;
570
0
  struct alternate_refs_data *cb = payload;
571
572
0
  if (!strbuf_realpath(&path, alternate->path, 0))
573
0
    goto out;
574
0
  if (!strbuf_strip_suffix(&path, "/objects"))
575
0
    goto out;
576
0
  base_len = path.len;
577
578
  /* Is this a git repository with refs? */
579
0
  strbuf_addstr(&path, "/refs");
580
0
  if (!is_directory(path.buf))
581
0
    goto out;
582
0
  strbuf_setlen(&path, base_len);
583
584
0
  read_alternate_refs(alternate->odb->repo, path.buf, cb->fn, cb->payload);
585
586
0
out:
587
0
  strbuf_release(&path);
588
0
  return 0;
589
0
}
590
591
void odb_for_each_alternate_ref(struct object_database *odb,
592
        odb_for_each_alternate_ref_fn cb, void *payload)
593
0
{
594
0
  struct alternate_refs_data data;
595
0
  data.fn = cb;
596
0
  data.payload = payload;
597
0
  odb_for_each_alternate(odb, refs_from_alternate_cb, &data);
598
0
}
599
600
int odb_for_each_alternate(struct object_database *odb,
601
       odb_for_each_alternate_fn cb, void *payload)
602
0
{
603
0
  struct odb_source *alternate;
604
0
  int r = 0;
605
606
0
  odb_prepare_alternates(odb);
607
0
  for (alternate = odb->sources->next; alternate; alternate = alternate->next) {
608
0
    r = cb(alternate, payload);
609
0
    if (r)
610
0
      break;
611
0
  }
612
0
  return r;
613
0
}
614
615
void odb_prepare_alternates(struct object_database *odb)
616
0
{
617
0
  struct strvec sources = STRVEC_INIT;
618
619
0
  if (odb->loaded_alternates)
620
0
    return;
621
622
0
  parse_alternates(odb->alternate_db, PATH_SEP, NULL, &sources);
623
0
  odb_source_read_alternates(odb->sources, &sources);
624
0
  for (size_t i = 0; i < sources.nr; i++)
625
0
    odb_add_alternate_recursively(odb, sources.v[i], 0);
626
627
0
  odb->loaded_alternates = 1;
628
629
0
  strvec_clear(&sources);
630
0
}
631
632
int odb_has_alternates(struct object_database *odb)
633
0
{
634
0
  odb_prepare_alternates(odb);
635
0
  return !!odb->sources->next;
636
0
}
637
638
int obj_read_use_lock = 0;
639
pthread_mutex_t obj_read_mutex;
640
641
void enable_obj_read_lock(void)
642
0
{
643
0
  if (obj_read_use_lock)
644
0
    return;
645
646
0
  obj_read_use_lock = 1;
647
0
  init_recursive_mutex(&obj_read_mutex);
648
0
}
649
650
void disable_obj_read_lock(void)
651
0
{
652
0
  if (!obj_read_use_lock)
653
0
    return;
654
655
0
  obj_read_use_lock = 0;
656
0
  pthread_mutex_destroy(&obj_read_mutex);
657
0
}
658
659
int fetch_if_missing = 1;
660
661
static int register_all_submodule_sources(struct object_database *odb)
662
0
{
663
0
  int ret = odb->submodule_source_paths.nr;
664
665
0
  for (size_t i = 0; i < odb->submodule_source_paths.nr; i++)
666
0
    odb_add_to_alternates_memory(odb,
667
0
               odb->submodule_source_paths.items[i].string);
668
0
  if (ret) {
669
0
    string_list_clear(&odb->submodule_source_paths, 0);
670
0
    trace2_data_intmax("submodule", odb->repo,
671
0
           "register_all_submodule_sources/registered", ret);
672
0
    if (git_env_bool("GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB", 0))
673
0
      BUG("register_all_submodule_sources() called");
674
0
  }
675
0
  return ret;
676
0
}
677
678
static int do_oid_object_info_extended(struct object_database *odb,
679
               const struct object_id *oid,
680
               struct object_info *oi, unsigned flags)
681
0
{
682
0
  const struct cached_object *co;
683
0
  const struct object_id *real = oid;
684
0
  int already_retried = 0;
685
686
0
  if (flags & OBJECT_INFO_LOOKUP_REPLACE)
687
0
    real = lookup_replace_object(odb->repo, oid);
688
689
0
  if (is_null_oid(real))
690
0
    return -1;
691
692
0
  co = find_cached_object(odb, real);
693
0
  if (co) {
694
0
    if (oi) {
695
0
      if (oi->typep)
696
0
        *(oi->typep) = co->type;
697
0
      if (oi->sizep)
698
0
        *(oi->sizep) = co->size;
699
0
      if (oi->disk_sizep)
700
0
        *(oi->disk_sizep) = 0;
701
0
      if (oi->delta_base_oid)
702
0
        oidclr(oi->delta_base_oid, odb->repo->hash_algo);
703
0
      if (oi->contentp)
704
0
        *oi->contentp = xmemdupz(co->buf, co->size);
705
0
      oi->whence = OI_CACHED;
706
0
    }
707
0
    return 0;
708
0
  }
709
710
0
  odb_prepare_alternates(odb);
711
712
0
  while (1) {
713
0
    struct odb_source *source;
714
715
    /* Most likely it's a loose object. */
716
0
    for (source = odb->sources; source; source = source->next) {
717
0
      if (!packfile_store_read_object_info(source->packfiles, real, oi, flags) ||
718
0
          !odb_source_loose_read_object_info(source, real, oi, flags))
719
0
        return 0;
720
0
    }
721
722
    /* Not a loose object; someone else may have just packed it. */
723
0
    if (!(flags & OBJECT_INFO_QUICK)) {
724
0
      odb_reprepare(odb->repo->objects);
725
0
      for (source = odb->sources; source; source = source->next)
726
0
        if (!packfile_store_read_object_info(source->packfiles, real, oi, flags))
727
0
          return 0;
728
0
    }
729
730
    /*
731
     * This might be an attempt at accessing a submodule object as
732
     * if it were in main object store (having called
733
     * `odb_add_submodule_source_by_path()` on that submodule's
734
     * ODB). If any such ODBs exist, register them and try again.
735
     */
736
0
    if (register_all_submodule_sources(odb))
737
      /* We added some alternates; retry */
738
0
      continue;
739
740
    /* Check if it is a missing object */
741
0
    if (fetch_if_missing && repo_has_promisor_remote(odb->repo) &&
742
0
        !already_retried &&
743
0
        !(flags & OBJECT_INFO_SKIP_FETCH_OBJECT)) {
744
0
      promisor_remote_get_direct(odb->repo, real, 1);
745
0
      already_retried = 1;
746
0
      continue;
747
0
    }
748
749
0
    if (flags & OBJECT_INFO_DIE_IF_CORRUPT) {
750
0
      const struct packed_git *p;
751
0
      if ((flags & OBJECT_INFO_LOOKUP_REPLACE) && !oideq(real, oid))
752
0
        die(_("replacement %s not found for %s"),
753
0
            oid_to_hex(real), oid_to_hex(oid));
754
0
      if ((p = has_packed_and_bad(odb->repo, real)))
755
0
        die(_("packed object %s (stored in %s) is corrupt"),
756
0
            oid_to_hex(real), p->pack_name);
757
0
    }
758
0
    return -1;
759
0
  }
760
0
}
761
762
static int oid_object_info_convert(struct repository *r,
763
           const struct object_id *input_oid,
764
           struct object_info *input_oi, unsigned flags)
765
0
{
766
0
  const struct git_hash_algo *input_algo = &hash_algos[input_oid->algo];
767
0
  int do_die = flags & OBJECT_INFO_DIE_IF_CORRUPT;
768
0
  enum object_type type;
769
0
  struct object_id oid, delta_base_oid;
770
0
  struct object_info new_oi, *oi;
771
0
  unsigned long size;
772
0
  void *content;
773
0
  int ret;
774
775
0
  if (repo_oid_to_algop(r, input_oid, r->hash_algo, &oid)) {
776
0
    if (do_die)
777
0
      die(_("missing mapping of %s to %s"),
778
0
          oid_to_hex(input_oid), r->hash_algo->name);
779
0
    return -1;
780
0
  }
781
782
  /* Is new_oi needed? */
783
0
  oi = input_oi;
784
0
  if (input_oi && (input_oi->delta_base_oid || input_oi->sizep ||
785
0
       input_oi->contentp)) {
786
0
    new_oi = *input_oi;
787
    /* Does delta_base_oid need to be converted? */
788
0
    if (input_oi->delta_base_oid)
789
0
      new_oi.delta_base_oid = &delta_base_oid;
790
    /* Will the attributes differ when converted? */
791
0
    if (input_oi->sizep || input_oi->contentp) {
792
0
      new_oi.contentp = &content;
793
0
      new_oi.sizep = &size;
794
0
      new_oi.typep = &type;
795
0
    }
796
0
    oi = &new_oi;
797
0
  }
798
799
0
  ret = odb_read_object_info_extended(r->objects, &oid, oi, flags);
800
0
  if (ret)
801
0
    return -1;
802
0
  if (oi == input_oi)
803
0
    return ret;
804
805
0
  if (new_oi.contentp) {
806
0
    struct strbuf outbuf = STRBUF_INIT;
807
808
0
    if (type != OBJ_BLOB) {
809
0
      ret = convert_object_file(r, &outbuf,
810
0
              r->hash_algo, input_algo,
811
0
              content, size, type, !do_die);
812
0
      free(content);
813
0
      if (ret == -1)
814
0
        return -1;
815
0
      size = outbuf.len;
816
0
      content = strbuf_detach(&outbuf, NULL);
817
0
    }
818
0
    if (input_oi->sizep)
819
0
      *input_oi->sizep = size;
820
0
    if (input_oi->contentp)
821
0
      *input_oi->contentp = content;
822
0
    else
823
0
      free(content);
824
0
    if (input_oi->typep)
825
0
      *input_oi->typep = type;
826
0
  }
827
0
  if (new_oi.delta_base_oid == &delta_base_oid) {
828
0
    if (repo_oid_to_algop(r, &delta_base_oid, input_algo,
829
0
         input_oi->delta_base_oid)) {
830
0
      if (do_die)
831
0
        die(_("missing mapping of %s to %s"),
832
0
            oid_to_hex(&delta_base_oid),
833
0
            input_algo->name);
834
0
      return -1;
835
0
    }
836
0
  }
837
0
  input_oi->whence = new_oi.whence;
838
0
  input_oi->u = new_oi.u;
839
0
  return ret;
840
0
}
841
842
int odb_read_object_info_extended(struct object_database *odb,
843
          const struct object_id *oid,
844
          struct object_info *oi,
845
          unsigned flags)
846
0
{
847
0
  int ret;
848
849
0
  if (oid->algo && (hash_algo_by_ptr(odb->repo->hash_algo) != oid->algo))
850
0
    return oid_object_info_convert(odb->repo, oid, oi, flags);
851
852
0
  obj_read_lock();
853
0
  ret = do_oid_object_info_extended(odb, oid, oi, flags);
854
0
  obj_read_unlock();
855
0
  return ret;
856
0
}
857
858
859
/* returns enum object_type or negative */
860
int odb_read_object_info(struct object_database *odb,
861
       const struct object_id *oid,
862
       unsigned long *sizep)
863
0
{
864
0
  enum object_type type;
865
0
  struct object_info oi = OBJECT_INFO_INIT;
866
867
0
  oi.typep = &type;
868
0
  oi.sizep = sizep;
869
0
  if (odb_read_object_info_extended(odb, oid, &oi,
870
0
            OBJECT_INFO_LOOKUP_REPLACE) < 0)
871
0
    return -1;
872
0
  return type;
873
0
}
874
875
int odb_pretend_object(struct object_database *odb,
876
           void *buf, unsigned long len, enum object_type type,
877
           struct object_id *oid)
878
0
{
879
0
  struct cached_object_entry *co;
880
0
  char *co_buf;
881
882
0
  hash_object_file(odb->repo->hash_algo, buf, len, type, oid);
883
0
  if (odb_has_object(odb, oid, 0) ||
884
0
      find_cached_object(odb, oid))
885
0
    return 0;
886
887
0
  ALLOC_GROW(odb->cached_objects,
888
0
       odb->cached_object_nr + 1, odb->cached_object_alloc);
889
0
  co = &odb->cached_objects[odb->cached_object_nr++];
890
0
  co->value.size = len;
891
0
  co->value.type = type;
892
0
  co_buf = xmalloc(len);
893
0
  memcpy(co_buf, buf, len);
894
0
  co->value.buf = co_buf;
895
0
  oidcpy(&co->oid, oid);
896
0
  return 0;
897
0
}
898
899
void *odb_read_object(struct object_database *odb,
900
          const struct object_id *oid,
901
          enum object_type *type,
902
          unsigned long *size)
903
0
{
904
0
  struct object_info oi = OBJECT_INFO_INIT;
905
0
  unsigned flags = OBJECT_INFO_DIE_IF_CORRUPT | OBJECT_INFO_LOOKUP_REPLACE;
906
0
  void *data;
907
908
0
  oi.typep = type;
909
0
  oi.sizep = size;
910
0
  oi.contentp = &data;
911
0
  if (odb_read_object_info_extended(odb, oid, &oi, flags))
912
0
    return NULL;
913
914
0
  return data;
915
0
}
916
917
void *odb_read_object_peeled(struct object_database *odb,
918
           const struct object_id *oid,
919
           enum object_type required_type,
920
           unsigned long *size,
921
           struct object_id *actual_oid_return)
922
0
{
923
0
  enum object_type type;
924
0
  void *buffer;
925
0
  unsigned long isize;
926
0
  struct object_id actual_oid;
927
928
0
  oidcpy(&actual_oid, oid);
929
0
  while (1) {
930
0
    int ref_length = -1;
931
0
    const char *ref_type = NULL;
932
933
0
    buffer = odb_read_object(odb, &actual_oid, &type, &isize);
934
0
    if (!buffer)
935
0
      return NULL;
936
0
    if (type == required_type) {
937
0
      *size = isize;
938
0
      if (actual_oid_return)
939
0
        oidcpy(actual_oid_return, &actual_oid);
940
0
      return buffer;
941
0
    }
942
    /* Handle references */
943
0
    else if (type == OBJ_COMMIT)
944
0
      ref_type = "tree ";
945
0
    else if (type == OBJ_TAG)
946
0
      ref_type = "object ";
947
0
    else {
948
0
      free(buffer);
949
0
      return NULL;
950
0
    }
951
0
    ref_length = strlen(ref_type);
952
953
0
    if (ref_length + odb->repo->hash_algo->hexsz > isize ||
954
0
        memcmp(buffer, ref_type, ref_length) ||
955
0
        get_oid_hex_algop((char *) buffer + ref_length, &actual_oid,
956
0
              odb->repo->hash_algo)) {
957
0
      free(buffer);
958
0
      return NULL;
959
0
    }
960
0
    free(buffer);
961
    /* Now we have the ID of the referred-to object in
962
     * actual_oid.  Check again. */
963
0
  }
964
0
}
965
966
int odb_has_object(struct object_database *odb, const struct object_id *oid,
967
         unsigned flags)
968
0
{
969
0
  unsigned object_info_flags = 0;
970
971
0
  if (!startup_info->have_repository)
972
0
    return 0;
973
0
  if (!(flags & HAS_OBJECT_RECHECK_PACKED))
974
0
    object_info_flags |= OBJECT_INFO_QUICK;
975
0
  if (!(flags & HAS_OBJECT_FETCH_PROMISOR))
976
0
    object_info_flags |= OBJECT_INFO_SKIP_FETCH_OBJECT;
977
978
0
  return odb_read_object_info_extended(odb, oid, NULL, object_info_flags) >= 0;
979
0
}
980
981
int odb_freshen_object(struct object_database *odb,
982
           const struct object_id *oid)
983
0
{
984
0
  struct odb_source *source;
985
986
0
  odb_prepare_alternates(odb);
987
0
  for (source = odb->sources; source; source = source->next) {
988
0
    if (packfile_store_freshen_object(source->packfiles, oid))
989
0
      return 1;
990
991
0
    if (odb_source_loose_freshen_object(source, oid))
992
0
      return 1;
993
0
  }
994
995
0
  return 0;
996
0
}
997
998
void odb_assert_oid_type(struct object_database *odb,
999
       const struct object_id *oid, enum object_type expect)
1000
0
{
1001
0
  enum object_type type = odb_read_object_info(odb, oid, NULL);
1002
0
  if (type < 0)
1003
0
    die(_("%s is not a valid object"), oid_to_hex(oid));
1004
0
  if (type != expect)
1005
0
    die(_("%s is not a valid '%s' object"), oid_to_hex(oid),
1006
0
        type_name(expect));
1007
0
}
1008
1009
int odb_write_object_ext(struct object_database *odb,
1010
       const void *buf, unsigned long len,
1011
       enum object_type type,
1012
       struct object_id *oid,
1013
       struct object_id *compat_oid,
1014
       unsigned flags)
1015
0
{
1016
0
  return odb_source_loose_write_object(odb->sources, buf, len, type,
1017
0
               oid, compat_oid, flags);
1018
0
}
1019
1020
int odb_write_object_stream(struct object_database *odb,
1021
          struct odb_write_stream *stream, size_t len,
1022
          struct object_id *oid)
1023
0
{
1024
0
  return odb_source_loose_write_stream(odb->sources, stream, len, oid);
1025
0
}
1026
1027
static void odb_update_commondir(const char *name UNUSED,
1028
         const char *old_cwd,
1029
         const char *new_cwd,
1030
         void *cb_data)
1031
0
{
1032
0
  struct object_database *odb = cb_data;
1033
0
  struct tmp_objdir *tmp_objdir;
1034
0
  struct odb_source *source;
1035
1036
0
  tmp_objdir = tmp_objdir_unapply_primary_odb();
1037
1038
  /*
1039
   * In theory, we only have to do this for the primary object source, as
1040
   * alternates' paths are always resolved to an absolute path.
1041
   */
1042
0
  for (source = odb->sources; source; source = source->next) {
1043
0
    char *path;
1044
1045
0
    if (is_absolute_path(source->path))
1046
0
      continue;
1047
1048
0
    path = reparent_relative_path(old_cwd, new_cwd,
1049
0
                source->path);
1050
1051
0
    free(source->path);
1052
0
    source->path = path;
1053
0
  }
1054
1055
0
  if (tmp_objdir)
1056
0
    tmp_objdir_reapply_primary_odb(tmp_objdir, old_cwd, new_cwd);
1057
0
}
1058
1059
struct object_database *odb_new(struct repository *repo,
1060
        const char *primary_source,
1061
        const char *secondary_sources)
1062
0
{
1063
0
  struct object_database *o = xmalloc(sizeof(*o));
1064
0
  char *to_free = NULL;
1065
1066
0
  memset(o, 0, sizeof(*o));
1067
0
  o->repo = repo;
1068
0
  pthread_mutex_init(&o->replace_mutex, NULL);
1069
0
  string_list_init_dup(&o->submodule_source_paths);
1070
1071
0
  if (!primary_source)
1072
0
    primary_source = to_free = xstrfmt("%s/objects", repo->commondir);
1073
0
  o->sources = odb_source_new(o, primary_source, true);
1074
0
  o->sources_tail = &o->sources->next;
1075
0
  o->alternate_db = xstrdup_or_null(secondary_sources);
1076
1077
0
  free(to_free);
1078
1079
0
  chdir_notify_register(NULL, odb_update_commondir, o);
1080
1081
0
  return o;
1082
0
}
1083
1084
void odb_close(struct object_database *o)
1085
0
{
1086
0
  struct odb_source *source;
1087
0
  for (source = o->sources; source; source = source->next)
1088
0
    packfile_store_close(source->packfiles);
1089
0
  close_commit_graph(o);
1090
0
}
1091
1092
static void odb_free_sources(struct object_database *o)
1093
0
{
1094
0
  while (o->sources) {
1095
0
    struct odb_source *next;
1096
1097
0
    next = o->sources->next;
1098
0
    odb_source_free(o->sources);
1099
0
    o->sources = next;
1100
0
  }
1101
0
  kh_destroy_odb_path_map(o->source_by_path);
1102
0
  o->source_by_path = NULL;
1103
0
}
1104
1105
void odb_free(struct object_database *o)
1106
0
{
1107
0
  if (!o)
1108
0
    return;
1109
1110
0
  free(o->alternate_db);
1111
1112
0
  oidmap_clear(&o->replace_map, 1);
1113
0
  pthread_mutex_destroy(&o->replace_mutex);
1114
1115
0
  odb_close(o);
1116
0
  odb_free_sources(o);
1117
1118
0
  for (size_t i = 0; i < o->cached_object_nr; i++)
1119
0
    free((char *) o->cached_objects[i].value.buf);
1120
0
  free(o->cached_objects);
1121
1122
0
  string_list_clear(&o->submodule_source_paths, 0);
1123
1124
0
  chdir_notify_unregister(NULL, odb_update_commondir, o);
1125
1126
0
  free(o);
1127
0
}
1128
1129
void odb_reprepare(struct object_database *o)
1130
0
{
1131
0
  struct odb_source *source;
1132
1133
0
  obj_read_lock();
1134
1135
  /*
1136
   * Reprepare alt odbs, in case the alternates file was modified
1137
   * during the course of this process. This only _adds_ odbs to
1138
   * the linked list, so existing odbs will continue to exist for
1139
   * the lifetime of the process.
1140
   */
1141
0
  o->loaded_alternates = 0;
1142
0
  odb_prepare_alternates(o);
1143
1144
0
  for (source = o->sources; source; source = source->next) {
1145
0
    odb_source_loose_reprepare(source);
1146
0
    packfile_store_reprepare(source->packfiles);
1147
0
  }
1148
1149
0
  o->approximate_object_count_valid = 0;
1150
1151
0
  obj_read_unlock();
1152
0
}
1153
1154
struct odb_transaction *odb_transaction_begin(struct object_database *odb)
1155
0
{
1156
0
  if (odb->transaction)
1157
0
    return NULL;
1158
1159
0
  odb->transaction = odb_transaction_files_begin(odb->sources);
1160
1161
0
  return odb->transaction;
1162
0
}
1163
1164
void odb_transaction_commit(struct odb_transaction *transaction)
1165
0
{
1166
0
  if (!transaction)
1167
0
    return;
1168
1169
  /*
1170
   * Ensure the transaction ending matches the pending transaction.
1171
   */
1172
0
  ASSERT(transaction == transaction->source->odb->transaction);
1173
1174
0
  transaction->commit(transaction);
1175
  transaction->source->odb->transaction = NULL;
1176
0
  free(transaction);
1177
0
}