Coverage Report

Created: 2026-03-31 06:24

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