From 1ace06644926bcf1f05e291e8a9476c977c25eeb Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Tue, 1 Jul 2025 14:22:13 +0200 Subject: object-store: rename `raw_object_store` to `object_database` The `raw_object_store` structure is the central entry point for reading and writing objects in a repository. The main purpose of this structure is to manage object directories and provide an interface to access and write objects in those object directories. Right now, many of the functions associated with the raw object store implicitly rely on `the_repository` to get access to its `objects` pointer, which is the `raw_object_store`. As we want to generally get rid of using `the_repository` across our codebase we will have to convert this implicit dependency on this global variable into an explicit parameter. This conversion can be done by simply passing in an explicit pointer to a repository and then using its `->objects` pointer. But there is a second effort underway, which is to make the object subsystem more selfcontained so that we can eventually have pluggable object backends. As such, passing in a repository wouldn't make a ton of sense, and the goal is to convert the object store interfaces such that we always pass in a reference to the `raw_object_store` instead. This will expose the `raw_object_store` type to a lot more callers though, which surfaces that this type is named somewhat awkwardly. The "raw_" prefix makes readers wonder whether there is a non-raw variant of the object store, but there isn't. Furthermore, we nowadays want to name functions in a way that they can be clearly attributed to a specific subsystem, but calling them e.g. `raw_object_store_has_object()` is just too unwieldy, even when dropping the "raw_" prefix. Instead, rename the structure to `object_database`. This term is already used a lot throughout our codebase, and it cannot easily be mistaken for "object directories", either. Furthermore, its acronym ODB is already well-known and works well as part of a function's name, like for example `odb_has_object()`. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- commit-graph.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'commit-graph.h') diff --git a/commit-graph.h b/commit-graph.h index 13f662827d..20d38c100c 100644 --- a/commit-graph.h +++ b/commit-graph.h @@ -26,7 +26,7 @@ void git_test_write_commit_graph_or_die(void); struct commit; struct bloom_filter_settings; struct repository; -struct raw_object_store; +struct object_database; struct string_list; char *get_commit_graph_filename(struct object_directory *odb); @@ -186,7 +186,7 @@ int write_commit_graph(struct object_directory *odb, int verify_commit_graph(struct repository *r, struct commit_graph *g, int flags); -void close_commit_graph(struct raw_object_store *); +void close_commit_graph(struct object_database *); void free_commit_graph(struct commit_graph *); /* -- cgit v1.2.3 From a1e2581a1e9ca2a85ae0a018ba5fb8fe5db3c322 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Tue, 1 Jul 2025 14:22:14 +0200 Subject: object-store: rename `object_directory` to `odb_source` The `object_directory` structure is used as an access point for a single object directory like ".git/objects". While the structure isn't yet fully self-contained, the intent is for it to eventually contain all information required to access objects in one specific location. While the name "object directory" is a good fit for now, this will change over time as we continue with the agenda to make pluggable object databases a thing. Eventually, objects may not be accessed via any kind of directory at all anymore, but they could instead be backed by any kind of durable storage mechanism. While it seems quite far-fetched for now, it is thinkable that eventually this might even be some form of a database, for example. As such, the current name of this structure will become worse over time as we evolve into the direction of pluggable ODBs. Immediate next steps will start to carve out proper self-contained object directories, which requires us to pass in these object directories as parameters. Based on our modern naming schema this means that those functions should then be named after their subsystem, which means that we would start to bake the current name into the codebase more and more. Let's preempt this by renaming the structure. There have been a couple alternatives that were discussed: - `odb_backend` was discarded because it led to the association that one object database has a single backend, but the model is that one alternate has one backend. Furthermore, "backend" is more about the actual backing implementation and less about the high-level concept. - `odb_alternate` was discarded because it is a bit of a stretch to also call the main object directory an "alternate". Instead, pick `odb_source` as the new name. It makes it sufficiently clear that there can be multiple sources and does not cause confusion when mixed with the already-existing "alternate" terminology. In the future, this change allows us to easily introduce for example a `odb_files_source` and other format-specific implementations. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- builtin/commit-graph.c | 18 +++---- builtin/count-objects.c | 4 +- builtin/fetch.c | 2 +- builtin/fsck.c | 14 ++--- builtin/gc.c | 14 ++--- builtin/grep.c | 2 +- builtin/multi-pack-index.c | 4 +- builtin/submodule--helper.c | 6 +-- bundle.c | 2 +- commit-graph.c | 94 +++++++++++++++++----------------- commit-graph.h | 14 ++--- diagnose.c | 8 +-- http-walker.c | 2 +- http.c | 4 +- loose.c | 42 +++++++-------- midx.c | 6 +-- object-file.c | 80 ++++++++++++++--------------- object-file.h | 8 +-- object-name.c | 6 +-- object-store.c | 122 ++++++++++++++++++++++---------------------- object-store.h | 38 +++++++++----- packfile.c | 16 +++--- path.c | 2 +- refs.c | 2 +- repository.c | 14 ++--- submodule-config.c | 2 +- t/helper/test-read-graph.c | 6 +-- tmp-objdir.c | 24 ++++----- 28 files changed, 284 insertions(+), 272 deletions(-) (limited to 'commit-graph.h') diff --git a/builtin/commit-graph.c b/builtin/commit-graph.c index a783a86e79..98a8431534 100644 --- a/builtin/commit-graph.c +++ b/builtin/commit-graph.c @@ -66,7 +66,7 @@ static int graph_verify(int argc, const char **argv, const char *prefix, struct repository *repo UNUSED) { struct commit_graph *graph = NULL; - struct object_directory *odb = NULL; + struct odb_source *source = NULL; char *graph_name; char *chain_name; enum { OPENED_NONE, OPENED_GRAPH, OPENED_CHAIN } opened = OPENED_NONE; @@ -101,9 +101,9 @@ static int graph_verify(int argc, const char **argv, const char *prefix, if (opts.progress) flags |= COMMIT_GRAPH_WRITE_PROGRESS; - odb = find_odb(the_repository, opts.obj_dir); - graph_name = get_commit_graph_filename(odb); - chain_name = get_commit_graph_chain_filename(odb); + source = find_odb(the_repository, opts.obj_dir); + graph_name = get_commit_graph_filename(source); + chain_name = get_commit_graph_chain_filename(source); if (open_commit_graph(graph_name, &fd, &st)) opened = OPENED_GRAPH; else if (errno != ENOENT) @@ -120,7 +120,7 @@ static int graph_verify(int argc, const char **argv, const char *prefix, if (opened == OPENED_NONE) return 0; else if (opened == OPENED_GRAPH) - graph = load_commit_graph_one_fd_st(the_repository, fd, &st, odb); + graph = load_commit_graph_one_fd_st(the_repository, fd, &st, source); else graph = load_commit_graph_chain_fd_st(the_repository, fd, &st, &incomplete_chain); @@ -221,7 +221,7 @@ static int graph_write(int argc, const char **argv, const char *prefix, struct string_list pack_indexes = STRING_LIST_INIT_DUP; struct strbuf buf = STRBUF_INIT; struct oidset commits = OIDSET_INIT; - struct object_directory *odb = NULL; + struct odb_source *source = NULL; int result = 0; enum commit_graph_write_flags flags = 0; struct progress *progress = NULL; @@ -289,10 +289,10 @@ static int graph_write(int argc, const char **argv, const char *prefix, git_env_bool(GIT_TEST_COMMIT_GRAPH_CHANGED_PATHS, 0)) flags |= COMMIT_GRAPH_WRITE_BLOOM_FILTERS; - odb = find_odb(the_repository, opts.obj_dir); + source = find_odb(the_repository, opts.obj_dir); if (opts.reachable) { - if (write_commit_graph_reachable(odb, flags, &write_opts)) + if (write_commit_graph_reachable(source, flags, &write_opts)) result = 1; goto cleanup; } @@ -318,7 +318,7 @@ static int graph_write(int argc, const char **argv, const char *prefix, stop_progress(&progress); } - if (write_commit_graph(odb, + if (write_commit_graph(source, opts.stdin_packs ? &pack_indexes : NULL, opts.stdin_commits ? &commits : NULL, flags, diff --git a/builtin/count-objects.c b/builtin/count-objects.c index a88c0c9c09..58e0af433d 100644 --- a/builtin/count-objects.c +++ b/builtin/count-objects.c @@ -80,10 +80,10 @@ static int count_cruft(const char *basename UNUSED, const char *path, return 0; } -static int print_alternate(struct object_directory *odb, void *data UNUSED) +static int print_alternate(struct odb_source *alternate, void *data UNUSED) { printf("alternate: "); - quote_c_style(odb->path, NULL, stdout, 0); + quote_c_style(alternate->path, NULL, stdout, 0); putchar('\n'); return 0; } diff --git a/builtin/fetch.c b/builtin/fetch.c index 40a0e8d244..a890e2864d 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -2653,7 +2653,7 @@ int cmd_fetch(int argc, commit_graph_flags |= COMMIT_GRAPH_WRITE_PROGRESS; trace2_region_enter("fetch", "write-commit-graph", the_repository); - write_commit_graph_reachable(the_repository->objects->odb, + write_commit_graph_reachable(the_repository->objects->sources, commit_graph_flags, NULL); trace2_region_leave("fetch", "write-commit-graph", the_repository); diff --git a/builtin/fsck.c b/builtin/fsck.c index e7d96a9c8e..6e1474f63d 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -956,7 +956,7 @@ int cmd_fsck(int argc, struct repository *repo UNUSED) { int i; - struct object_directory *odb; + struct odb_source *source; /* fsck knows how to handle missing promisor objects */ fetch_if_missing = 0; @@ -998,8 +998,8 @@ int cmd_fsck(int argc, mark_packed_for_connectivity, NULL, 0); } else { prepare_alt_odb(the_repository); - for (odb = the_repository->objects->odb; odb; odb = odb->next) - fsck_object_dir(odb->path); + for (source = the_repository->objects->sources; source; source = source->next) + fsck_object_dir(source->path); if (check_full) { struct packed_git *p; @@ -1109,11 +1109,11 @@ int cmd_fsck(int argc, struct child_process commit_graph_verify = CHILD_PROCESS_INIT; prepare_alt_odb(the_repository); - for (odb = the_repository->objects->odb; odb; odb = odb->next) { + for (source = the_repository->objects->sources; source; source = source->next) { child_process_init(&commit_graph_verify); commit_graph_verify.git_cmd = 1; strvec_pushl(&commit_graph_verify.args, "commit-graph", - "verify", "--object-dir", odb->path, NULL); + "verify", "--object-dir", source->path, NULL); if (show_progress) strvec_push(&commit_graph_verify.args, "--progress"); else @@ -1127,11 +1127,11 @@ int cmd_fsck(int argc, struct child_process midx_verify = CHILD_PROCESS_INIT; prepare_alt_odb(the_repository); - for (odb = the_repository->objects->odb; odb; odb = odb->next) { + for (source = the_repository->objects->sources; source; source = source->next) { child_process_init(&midx_verify); midx_verify.git_cmd = 1; strvec_pushl(&midx_verify.args, "multi-pack-index", - "verify", "--object-dir", odb->path, NULL); + "verify", "--object-dir", source->path, NULL); if (show_progress) strvec_push(&midx_verify.args, "--progress"); else diff --git a/builtin/gc.c b/builtin/gc.c index e33ba946e4..50a09eb07e 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -1018,7 +1018,7 @@ int cmd_gc(int argc, } if (the_repository->settings.gc_write_commit_graph == 1) - write_commit_graph_reachable(the_repository->objects->odb, + write_commit_graph_reachable(the_repository->objects->sources, !quiet && !daemonized ? COMMIT_GRAPH_WRITE_PROGRESS : 0, NULL); @@ -1271,7 +1271,7 @@ static int loose_object_auto_condition(struct gc_config *cfg UNUSED) if (loose_object_auto_limit < 0) return 1; - return for_each_loose_file_in_objdir(the_repository->objects->odb->path, + return for_each_loose_file_in_objdir(the_repository->objects->sources->path, loose_object_count, NULL, NULL, &count); } @@ -1306,7 +1306,7 @@ static int pack_loose(struct maintenance_run_opts *opts) * Do not start pack-objects process * if there are no loose objects. */ - if (!for_each_loose_file_in_objdir(r->objects->odb->path, + if (!for_each_loose_file_in_objdir(r->objects->sources->path, bail_on_loose, NULL, NULL, NULL)) return 0; @@ -1318,7 +1318,7 @@ static int pack_loose(struct maintenance_run_opts *opts) strvec_push(&pack_proc.args, "--quiet"); else strvec_push(&pack_proc.args, "--no-quiet"); - strvec_pushf(&pack_proc.args, "%s/pack/loose", r->objects->odb->path); + strvec_pushf(&pack_proc.args, "%s/pack/loose", r->objects->sources->path); pack_proc.in = -1; @@ -1346,7 +1346,7 @@ static int pack_loose(struct maintenance_run_opts *opts) else if (data.batch_size > 0) data.batch_size--; /* Decrease for equality on limit. */ - for_each_loose_file_in_objdir(r->objects->odb->path, + for_each_loose_file_in_objdir(r->objects->sources->path, write_loose_object_to_stdin, NULL, NULL, @@ -1611,7 +1611,7 @@ static int maintenance_run_tasks(struct maintenance_run_opts *opts, int result = 0; struct lock_file lk; struct repository *r = the_repository; - char *lock_path = xstrfmt("%s/maintenance", r->objects->odb->path); + char *lock_path = xstrfmt("%s/maintenance", r->objects->sources->path); if (hold_lock_file_for_update(&lk, lock_path, LOCK_NO_DEREF) < 0) { /* @@ -3083,7 +3083,7 @@ static int update_background_schedule(const struct maintenance_start_opts *opts, unsigned int i; int result = 0; struct lock_file lk; - char *lock_path = xstrfmt("%s/schedule", the_repository->objects->odb->path); + char *lock_path = xstrfmt("%s/schedule", the_repository->objects->sources->path); if (hold_lock_file_for_update(&lk, lock_path, LOCK_NO_DEREF) < 0) { if (errno == EEXIST) diff --git a/builtin/grep.c b/builtin/grep.c index 3ce574a605..76b1938bba 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -505,7 +505,7 @@ static int grep_submodule(struct grep_opt *opt, * lazily registered as alternates when needed (and except in an * unexpected code interaction, it won't be needed). */ - add_submodule_odb_by_path(subrepo->objects->odb->path); + add_submodule_odb_by_path(subrepo->objects->sources->path); obj_read_unlock(); memcpy(&subopt, opt, sizeof(subopt)); diff --git a/builtin/multi-pack-index.c b/builtin/multi-pack-index.c index 69a9750732..f55bf53da8 100644 --- a/builtin/multi-pack-index.c +++ b/builtin/multi-pack-index.c @@ -294,8 +294,8 @@ int cmd_multi_pack_index(int argc, if (the_repository && the_repository->objects && - the_repository->objects->odb) - opts.object_dir = xstrdup(the_repository->objects->odb->path); + the_repository->objects->sources) + opts.object_dir = xstrdup(the_repository->objects->sources->path); argc = parse_options(argc, argv, prefix, options, builtin_multi_pack_index_usage, 0); diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 53da2116dd..758bc6d0f2 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -1582,7 +1582,7 @@ static const char alternate_error_advice[] = N_( ); static int add_possible_reference_from_superproject( - struct object_directory *odb, void *sas_cb) + struct odb_source *alt_odb, void *sas_cb) { struct submodule_alternate_setup *sas = sas_cb; size_t len; @@ -1591,12 +1591,12 @@ static int add_possible_reference_from_superproject( * If the alternate object store is another repository, try the * standard layout with .git/(modules/)+/objects */ - if (strip_suffix(odb->path, "/objects", &len)) { + if (strip_suffix(alt_odb->path, "/objects", &len)) { struct repository alternate; char *sm_alternate; struct strbuf sb = STRBUF_INIT; struct strbuf err = STRBUF_INIT; - strbuf_add(&sb, odb->path, len); + strbuf_add(&sb, alt_odb->path, len); if (repo_init(&alternate, sb.buf, NULL) < 0) die(_("could not get a repository handle for gitdir '%s'"), diff --git a/bundle.c b/bundle.c index b0a3fee2ef..2ce7525f90 100644 --- a/bundle.c +++ b/bundle.c @@ -233,7 +233,7 @@ int verify_bundle(struct repository *r, .quiet = 1, }; - if (!r || !r->objects || !r->objects->odb) + if (!r || !r->objects || !r->objects->sources) return error(_("need a repository to verify a bundle")); for (i = 0; i < p->nr; i++) { diff --git a/commit-graph.c b/commit-graph.c index 905fcbdf0e..12d32cdad1 100644 --- a/commit-graph.c +++ b/commit-graph.c @@ -37,7 +37,7 @@ void git_test_write_commit_graph_or_die(void) if (git_env_bool(GIT_TEST_COMMIT_GRAPH_CHANGED_PATHS, 0)) flags = COMMIT_GRAPH_WRITE_BLOOM_FILTERS; - if (write_commit_graph_reachable(the_repository->objects->odb, + if (write_commit_graph_reachable(the_repository->objects->sources, flags, NULL)) die("failed to write commit-graph under GIT_TEST_COMMIT_GRAPH"); } @@ -191,21 +191,21 @@ static int commit_gen_cmp(const void *va, const void *vb) return 0; } -char *get_commit_graph_filename(struct object_directory *obj_dir) +char *get_commit_graph_filename(struct odb_source *source) { - return xstrfmt("%s/info/commit-graph", obj_dir->path); + return xstrfmt("%s/info/commit-graph", source->path); } -static char *get_split_graph_filename(struct object_directory *odb, +static char *get_split_graph_filename(struct odb_source *source, const char *oid_hex) { - return xstrfmt("%s/info/commit-graphs/graph-%s.graph", odb->path, + return xstrfmt("%s/info/commit-graphs/graph-%s.graph", source->path, oid_hex); } -char *get_commit_graph_chain_filename(struct object_directory *odb) +char *get_commit_graph_chain_filename(struct odb_source *source) { - return xstrfmt("%s/info/commit-graphs/commit-graph-chain", odb->path); + return xstrfmt("%s/info/commit-graphs/commit-graph-chain", source->path); } static struct commit_graph *alloc_commit_graph(void) @@ -250,7 +250,7 @@ int open_commit_graph(const char *graph_file, int *fd, struct stat *st) struct commit_graph *load_commit_graph_one_fd_st(struct repository *r, int fd, struct stat *st, - struct object_directory *odb) + struct odb_source *source) { void *graph_map; size_t graph_size; @@ -269,7 +269,7 @@ struct commit_graph *load_commit_graph_one_fd_st(struct repository *r, ret = parse_commit_graph(&r->settings, graph_map, graph_size); if (ret) - ret->odb = odb; + ret->odb_source = source; else munmap(graph_map, graph_size); @@ -487,7 +487,7 @@ free_and_return: static struct commit_graph *load_commit_graph_one(struct repository *r, const char *graph_file, - struct object_directory *odb) + struct odb_source *source) { struct stat st; @@ -498,7 +498,7 @@ static struct commit_graph *load_commit_graph_one(struct repository *r, if (!open_ok) return NULL; - g = load_commit_graph_one_fd_st(r, fd, &st, odb); + g = load_commit_graph_one_fd_st(r, fd, &st, source); if (g) g->filename = xstrdup(graph_file); @@ -507,10 +507,10 @@ static struct commit_graph *load_commit_graph_one(struct repository *r, } static struct commit_graph *load_commit_graph_v1(struct repository *r, - struct object_directory *odb) + struct odb_source *source) { - char *graph_name = get_commit_graph_filename(odb); - struct commit_graph *g = load_commit_graph_one(r, graph_name, odb); + char *graph_name = get_commit_graph_filename(source); + struct commit_graph *g = load_commit_graph_one(r, graph_name, source); free(graph_name); return g; @@ -652,7 +652,7 @@ struct commit_graph *load_commit_graph_chain_fd_st(struct repository *r, prepare_alt_odb(r); for (i = 0; i < count; i++) { - struct object_directory *odb; + struct odb_source *source; if (strbuf_getline_lf(&line, fp) == EOF) break; @@ -665,9 +665,9 @@ struct commit_graph *load_commit_graph_chain_fd_st(struct repository *r, } valid = 0; - for (odb = r->objects->odb; odb; odb = odb->next) { - char *graph_name = get_split_graph_filename(odb, line.buf); - struct commit_graph *g = load_commit_graph_one(r, graph_name, odb); + for (source = r->objects->sources; source; source = source->next) { + char *graph_name = get_split_graph_filename(source, line.buf); + struct commit_graph *g = load_commit_graph_one(r, graph_name, source); free(graph_name); @@ -701,9 +701,9 @@ struct commit_graph *load_commit_graph_chain_fd_st(struct repository *r, } static struct commit_graph *load_commit_graph_chain(struct repository *r, - struct object_directory *odb) + struct odb_source *source) { - char *chain_file = get_commit_graph_chain_filename(odb); + char *chain_file = get_commit_graph_chain_filename(source); struct stat st; int fd; struct commit_graph *g = NULL; @@ -719,24 +719,24 @@ static struct commit_graph *load_commit_graph_chain(struct repository *r, } struct commit_graph *read_commit_graph_one(struct repository *r, - struct object_directory *odb) + struct odb_source *source) { - struct commit_graph *g = load_commit_graph_v1(r, odb); + struct commit_graph *g = load_commit_graph_v1(r, source); if (!g) - g = load_commit_graph_chain(r, odb); + g = load_commit_graph_chain(r, source); return g; } static void prepare_commit_graph_one(struct repository *r, - struct object_directory *odb) + struct odb_source *source) { if (r->objects->commit_graph) return; - r->objects->commit_graph = read_commit_graph_one(r, odb); + r->objects->commit_graph = read_commit_graph_one(r, source); } /* @@ -747,7 +747,7 @@ static void prepare_commit_graph_one(struct repository *r, */ static int prepare_commit_graph(struct repository *r) { - struct object_directory *odb; + struct odb_source *source; /* * Early return if there is no git dir or if the commit graph is @@ -779,10 +779,10 @@ static int prepare_commit_graph(struct repository *r) return 0; prepare_alt_odb(r); - for (odb = r->objects->odb; - !r->objects->commit_graph && odb; - odb = odb->next) - prepare_commit_graph_one(r, odb); + for (source = r->objects->sources; + !r->objects->commit_graph && source; + source = source->next) + prepare_commit_graph_one(r, source); return !!r->objects->commit_graph; } @@ -1137,7 +1137,7 @@ struct packed_commit_list { struct write_commit_graph_context { struct repository *r; - struct object_directory *odb; + struct odb_source *odb_source; char *graph_name; struct oid_array oids; struct packed_commit_list commits; @@ -1870,7 +1870,7 @@ static int add_ref_to_set(const char *refname UNUSED, return 0; } -int write_commit_graph_reachable(struct object_directory *odb, +int write_commit_graph_reachable(struct odb_source *source, enum commit_graph_write_flags flags, const struct commit_graph_opts *opts) { @@ -1890,7 +1890,7 @@ int write_commit_graph_reachable(struct object_directory *odb, stop_progress(&data.progress); - result = write_commit_graph(odb, NULL, &commits, + result = write_commit_graph(source, NULL, &commits, flags, opts); oidset_clear(&commits); @@ -1906,7 +1906,7 @@ static int fill_oids_from_packs(struct write_commit_graph_context *ctx, int dirlen; int ret = 0; - strbuf_addf(&packname, "%s/pack/", ctx->odb->path); + strbuf_addf(&packname, "%s/pack/", ctx->odb_source->path); dirlen = packname.len; if (ctx->report_progress) { strbuf_addf(&progress_title, @@ -2060,10 +2060,10 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx) strbuf_addf(&tmp_file, "%s/info/commit-graphs/tmp_graph_XXXXXX", - ctx->odb->path); + ctx->odb_source->path); ctx->graph_name = strbuf_detach(&tmp_file, NULL); } else { - ctx->graph_name = get_commit_graph_filename(ctx->odb); + ctx->graph_name = get_commit_graph_filename(ctx->odb_source); } if (safe_create_leading_directories(the_repository, ctx->graph_name)) { @@ -2073,7 +2073,7 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx) } if (ctx->split) { - char *lock_name = get_commit_graph_chain_filename(ctx->odb); + char *lock_name = get_commit_graph_chain_filename(ctx->odb_source); hold_lock_file_for_update_mode(&lk, lock_name, LOCK_DIE_ON_ERROR, 0444); @@ -2161,7 +2161,7 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx) if (ctx->split && ctx->base_graph_name && ctx->num_commit_graphs_after > 1) { char *new_base_hash = xstrdup(oid_to_hex(&ctx->new_base_graph->oid)); - char *new_base_name = get_split_graph_filename(ctx->new_base_graph->odb, new_base_hash); + char *new_base_name = get_split_graph_filename(ctx->new_base_graph->odb_source, new_base_hash); free(ctx->commit_graph_filenames_after[ctx->num_commit_graphs_after - 2]); free(ctx->commit_graph_hash_after[ctx->num_commit_graphs_after - 2]); @@ -2201,14 +2201,14 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx) } } } else { - char *graph_name = get_commit_graph_filename(ctx->odb); + char *graph_name = get_commit_graph_filename(ctx->odb_source); unlink(graph_name); free(graph_name); } free(ctx->commit_graph_hash_after[ctx->num_commit_graphs_after - 1]); ctx->commit_graph_hash_after[ctx->num_commit_graphs_after - 1] = xstrdup(hash_to_hex(file_hash)); - final_graph_name = get_split_graph_filename(ctx->odb, + final_graph_name = get_split_graph_filename(ctx->odb_source, ctx->commit_graph_hash_after[ctx->num_commit_graphs_after - 1]); free(ctx->commit_graph_filenames_after[ctx->num_commit_graphs_after - 1]); ctx->commit_graph_filenames_after[ctx->num_commit_graphs_after - 1] = final_graph_name; @@ -2259,7 +2259,7 @@ static void split_graph_merge_strategy(struct write_commit_graph_context *ctx) flags != COMMIT_GRAPH_SPLIT_REPLACE) { while (g && (g->num_commits <= st_mult(size_mult, num_commits) || (max_commits && num_commits > max_commits))) { - if (g->odb != ctx->odb) + if (g->odb_source != ctx->odb_source) break; if (unsigned_add_overflows(num_commits, g->num_commits)) @@ -2281,10 +2281,10 @@ static void split_graph_merge_strategy(struct write_commit_graph_context *ctx) "should be 1 with --split=replace"); if (ctx->num_commit_graphs_after == 2) { - char *old_graph_name = get_commit_graph_filename(g->odb); + char *old_graph_name = get_commit_graph_filename(g->odb_source); if (!strcmp(g->filename, old_graph_name) && - g->odb != ctx->odb) { + g->odb_source != ctx->odb_source) { ctx->num_commit_graphs_after = 1; ctx->new_base_graph = NULL; } @@ -2456,13 +2456,13 @@ static void expire_commit_graphs(struct write_commit_graph_context *ctx) if (ctx->opts && ctx->opts->expire_time) expire_time = ctx->opts->expire_time; if (!ctx->split) { - char *chain_file_name = get_commit_graph_chain_filename(ctx->odb); + char *chain_file_name = get_commit_graph_chain_filename(ctx->odb_source); unlink(chain_file_name); free(chain_file_name); ctx->num_commit_graphs_after = 0; } - strbuf_addstr(&path, ctx->odb->path); + strbuf_addstr(&path, ctx->odb_source->path); strbuf_addstr(&path, "/info/commit-graphs"); dir = opendir(path.buf); @@ -2504,7 +2504,7 @@ out: strbuf_release(&path); } -int write_commit_graph(struct object_directory *odb, +int write_commit_graph(struct odb_source *source, const struct string_list *const pack_indexes, struct oidset *commits, enum commit_graph_write_flags flags, @@ -2513,7 +2513,7 @@ int write_commit_graph(struct object_directory *odb, struct repository *r = the_repository; struct write_commit_graph_context ctx = { .r = r, - .odb = odb, + .odb_source = source, .append = flags & COMMIT_GRAPH_WRITE_APPEND ? 1 : 0, .report_progress = flags & COMMIT_GRAPH_WRITE_PROGRESS ? 1 : 0, .split = flags & COMMIT_GRAPH_WRITE_SPLIT ? 1 : 0, diff --git a/commit-graph.h b/commit-graph.h index 20d38c100c..0e661db1b5 100644 --- a/commit-graph.h +++ b/commit-graph.h @@ -29,8 +29,8 @@ struct repository; struct object_database; struct string_list; -char *get_commit_graph_filename(struct object_directory *odb); -char *get_commit_graph_chain_filename(struct object_directory *odb); +char *get_commit_graph_filename(struct odb_source *source); +char *get_commit_graph_chain_filename(struct odb_source *source); int open_commit_graph(const char *graph_file, int *fd, struct stat *st); int open_commit_graph_chain(const char *chain_file, int *fd, struct stat *st); @@ -89,7 +89,7 @@ struct commit_graph { uint32_t num_commits; struct object_id oid; char *filename; - struct object_directory *odb; + struct odb_source *odb_source; uint32_t num_commits_in_base; unsigned int read_generation_data; @@ -115,12 +115,12 @@ struct commit_graph { struct commit_graph *load_commit_graph_one_fd_st(struct repository *r, int fd, struct stat *st, - struct object_directory *odb); + struct odb_source *source); struct commit_graph *load_commit_graph_chain_fd_st(struct repository *r, int fd, struct stat *st, int *incomplete_chain); struct commit_graph *read_commit_graph_one(struct repository *r, - struct object_directory *odb); + struct odb_source *source); struct repo_settings; @@ -173,10 +173,10 @@ struct commit_graph_opts { * is not compatible with the commit-graph feature, then the * methods will return 0 without writing a commit-graph. */ -int write_commit_graph_reachable(struct object_directory *odb, +int write_commit_graph_reachable(struct odb_source *source, enum commit_graph_write_flags flags, const struct commit_graph_opts *opts); -int write_commit_graph(struct object_directory *odb, +int write_commit_graph(struct odb_source *source, const struct string_list *pack_indexes, struct oidset *commits, enum commit_graph_write_flags flags, diff --git a/diagnose.c b/diagnose.c index b1be74be98..d08d5643aa 100644 --- a/diagnose.c +++ b/diagnose.c @@ -59,13 +59,13 @@ static void dir_file_stats_objects(const char *full_path, (uintmax_t)st.st_size); } -static int dir_file_stats(struct object_directory *object_dir, void *data) +static int dir_file_stats(struct odb_source *source, void *data) { struct strbuf *buf = data; - strbuf_addf(buf, "Contents of %s:\n", object_dir->path); + strbuf_addf(buf, "Contents of %s:\n", source->path); - for_each_file_in_pack_dir(object_dir->path, dir_file_stats_objects, + for_each_file_in_pack_dir(source->path, dir_file_stats_objects, data); return 0; @@ -228,7 +228,7 @@ int create_diagnostics_archive(struct repository *r, strbuf_reset(&buf); strbuf_addstr(&buf, "--add-virtual-file=packs-local.txt:"); - dir_file_stats(r->objects->odb, &buf); + dir_file_stats(r->objects->sources, &buf); foreach_alt_odb(dir_file_stats, &buf); strvec_push(&archiver_args, buf.buf); diff --git a/http-walker.c b/http-walker.c index 463f7b119a..c374e6b205 100644 --- a/http-walker.c +++ b/http-walker.c @@ -543,7 +543,7 @@ static int fetch_object(struct walker *walker, const struct object_id *oid) ret = error("File %s has bad hash", hex); } else if (req->rename < 0) { struct strbuf buf = STRBUF_INIT; - odb_loose_path(the_repository->objects->odb, &buf, &req->oid); + odb_loose_path(the_repository->objects->sources, &buf, &req->oid); ret = error("unable to write sha1 filename %s", buf.buf); strbuf_release(&buf); } diff --git a/http.c b/http.c index 3c029cf894..5e15bbab3f 100644 --- a/http.c +++ b/http.c @@ -2662,7 +2662,7 @@ struct http_object_request *new_http_object_request(const char *base_url, oidcpy(&freq->oid, oid); freq->localfile = -1; - odb_loose_path(the_repository->objects->odb, &filename, oid); + odb_loose_path(the_repository->objects->sources, &filename, oid); strbuf_addf(&freq->tmpfile, "%s.temp", filename.buf); strbuf_addf(&prevfile, "%s.prev", filename.buf); @@ -2814,7 +2814,7 @@ int finish_http_object_request(struct http_object_request *freq) unlink_or_warn(freq->tmpfile.buf); return -1; } - odb_loose_path(the_repository->objects->odb, &filename, &freq->oid); + odb_loose_path(the_repository->objects->sources, &filename, &freq->oid); freq->rename = finalize_object_file(freq->tmpfile.buf, filename.buf); strbuf_release(&filename); diff --git a/loose.c b/loose.c index bb602aaa36..fe65d5b9b0 100644 --- a/loose.c +++ b/loose.c @@ -44,36 +44,36 @@ static int insert_oid_pair(kh_oid_map_t *map, const struct object_id *key, const return 1; } -static int insert_loose_map(struct object_directory *odb, +static int insert_loose_map(struct odb_source *source, const struct object_id *oid, const struct object_id *compat_oid) { - struct loose_object_map *map = odb->loose_map; + struct loose_object_map *map = source->loose_map; int inserted = 0; inserted |= insert_oid_pair(map->to_compat, oid, compat_oid); inserted |= insert_oid_pair(map->to_storage, compat_oid, oid); if (inserted) - oidtree_insert(odb->loose_objects_cache, compat_oid); + oidtree_insert(source->loose_objects_cache, compat_oid); return inserted; } -static int load_one_loose_object_map(struct repository *repo, struct object_directory *dir) +static int load_one_loose_object_map(struct repository *repo, struct odb_source *source) { struct strbuf buf = STRBUF_INIT, path = STRBUF_INIT; FILE *fp; - if (!dir->loose_map) - loose_object_map_init(&dir->loose_map); - if (!dir->loose_objects_cache) { - ALLOC_ARRAY(dir->loose_objects_cache, 1); - oidtree_init(dir->loose_objects_cache); + if (!source->loose_map) + loose_object_map_init(&source->loose_map); + if (!source->loose_objects_cache) { + ALLOC_ARRAY(source->loose_objects_cache, 1); + oidtree_init(source->loose_objects_cache); } - insert_loose_map(dir, repo->hash_algo->empty_tree, repo->compat_hash_algo->empty_tree); - insert_loose_map(dir, repo->hash_algo->empty_blob, repo->compat_hash_algo->empty_blob); - insert_loose_map(dir, repo->hash_algo->null_oid, repo->compat_hash_algo->null_oid); + insert_loose_map(source, repo->hash_algo->empty_tree, repo->compat_hash_algo->empty_tree); + insert_loose_map(source, repo->hash_algo->empty_blob, repo->compat_hash_algo->empty_blob); + insert_loose_map(source, repo->hash_algo->null_oid, repo->compat_hash_algo->null_oid); repo_common_path_replace(repo, &path, "objects/loose-object-idx"); fp = fopen(path.buf, "rb"); @@ -93,7 +93,7 @@ static int load_one_loose_object_map(struct repository *repo, struct object_dire parse_oid_hex_algop(p, &compat_oid, &p, repo->compat_hash_algo) || p != buf.buf + buf.len) goto err; - insert_loose_map(dir, &oid, &compat_oid); + insert_loose_map(source, &oid, &compat_oid); } strbuf_release(&buf); @@ -107,15 +107,15 @@ err: int repo_read_loose_object_map(struct repository *repo) { - struct object_directory *dir; + struct odb_source *source; if (!should_use_loose_object_map(repo)) return 0; prepare_alt_odb(repo); - for (dir = repo->objects->odb; dir; dir = dir->next) { - if (load_one_loose_object_map(repo, dir) < 0) { + for (source = repo->objects->sources; source; source = source->next) { + if (load_one_loose_object_map(repo, source) < 0) { return -1; } } @@ -124,7 +124,7 @@ int repo_read_loose_object_map(struct repository *repo) int repo_write_loose_object_map(struct repository *repo) { - kh_oid_map_t *map = repo->objects->odb->loose_map->to_compat; + kh_oid_map_t *map = repo->objects->sources->loose_map->to_compat; struct lock_file lock; int fd; khiter_t iter; @@ -212,7 +212,7 @@ int repo_add_loose_object_map(struct repository *repo, const struct object_id *o if (!should_use_loose_object_map(repo)) return 0; - inserted = insert_loose_map(repo->objects->odb, oid, compat_oid); + inserted = insert_loose_map(repo->objects->sources, oid, compat_oid); if (inserted) return write_one_object(repo, oid, compat_oid); return 0; @@ -223,12 +223,12 @@ int repo_loose_object_map_oid(struct repository *repo, const struct git_hash_algo *to, struct object_id *dest) { - struct object_directory *dir; + struct odb_source *source; kh_oid_map_t *map; khiter_t pos; - for (dir = repo->objects->odb; dir; dir = dir->next) { - struct loose_object_map *loose_map = dir->loose_map; + for (source = repo->objects->sources; source; source = source->next) { + struct loose_object_map *loose_map = source->loose_map; if (!loose_map) continue; map = (to == repo->compat_hash_algo) ? diff --git a/midx.c b/midx.c index cd6e766ce2..3c5bc82173 100644 --- a/midx.c +++ b/midx.c @@ -832,7 +832,7 @@ void clear_midx_file(struct repository *r) { struct strbuf midx = STRBUF_INIT; - get_midx_filename(r->hash_algo, &midx, r->objects->odb->path); + get_midx_filename(r->hash_algo, &midx, r->objects->sources->path); if (r->objects && r->objects->multi_pack_index) { close_midx(r->objects->multi_pack_index); @@ -842,8 +842,8 @@ void clear_midx_file(struct repository *r) if (remove_path(midx.buf)) die(_("failed to clear multi-pack-index at %s"), midx.buf); - clear_midx_files_ext(r->objects->odb->path, MIDX_EXT_BITMAP, NULL); - clear_midx_files_ext(r->objects->odb->path, MIDX_EXT_REV, NULL); + clear_midx_files_ext(r->objects->sources->path, MIDX_EXT_BITMAP, NULL); + clear_midx_files_ext(r->objects->sources->path, MIDX_EXT_REV, NULL); strbuf_release(&midx); } diff --git a/object-file.c b/object-file.c index 1ac04c2891..6bad1d3dd1 100644 --- a/object-file.c +++ b/object-file.c @@ -55,12 +55,12 @@ static void fill_loose_path(struct strbuf *buf, const struct object_id *oid) } } -const char *odb_loose_path(struct object_directory *odb, +const char *odb_loose_path(struct odb_source *source, struct strbuf *buf, const struct object_id *oid) { strbuf_reset(buf); - strbuf_addstr(buf, odb->path); + strbuf_addstr(buf, source->path); strbuf_addch(buf, '/'); fill_loose_path(buf, oid); return buf->buf; @@ -88,27 +88,27 @@ int check_and_freshen_file(const char *fn, int freshen) return 1; } -static int check_and_freshen_odb(struct object_directory *odb, +static int check_and_freshen_odb(struct odb_source *source, const struct object_id *oid, int freshen) { static struct strbuf path = STRBUF_INIT; - odb_loose_path(odb, &path, oid); + odb_loose_path(source, &path, oid); return check_and_freshen_file(path.buf, freshen); } static int check_and_freshen_local(const struct object_id *oid, int freshen) { - return check_and_freshen_odb(the_repository->objects->odb, oid, freshen); + return check_and_freshen_odb(the_repository->objects->sources, oid, freshen); } static int check_and_freshen_nonlocal(const struct object_id *oid, int freshen) { - struct object_directory *odb; + struct odb_source *source; prepare_alt_odb(the_repository); - for (odb = the_repository->objects->odb->next; odb; odb = odb->next) { - if (check_and_freshen_odb(odb, oid, freshen)) + for (source = the_repository->objects->sources->next; source; source = source->next) { + if (check_and_freshen_odb(source, oid, freshen)) return 1; } return 0; @@ -202,12 +202,12 @@ int stream_object_signature(struct repository *r, const struct object_id *oid) static int stat_loose_object(struct repository *r, const struct object_id *oid, struct stat *st, const char **path) { - struct object_directory *odb; + struct odb_source *source; static struct strbuf buf = STRBUF_INIT; prepare_alt_odb(r); - for (odb = r->objects->odb; odb; odb = odb->next) { - *path = odb_loose_path(odb, &buf, oid); + for (source = r->objects->sources; source; source = source->next) { + *path = odb_loose_path(source, &buf, oid); if (!lstat(*path, st)) return 0; } @@ -223,13 +223,13 @@ static int open_loose_object(struct repository *r, const struct object_id *oid, const char **path) { int fd; - struct object_directory *odb; + struct odb_source *source; int most_interesting_errno = ENOENT; static struct strbuf buf = STRBUF_INIT; prepare_alt_odb(r); - for (odb = r->objects->odb; odb; odb = odb->next) { - *path = odb_loose_path(odb, &buf, oid); + for (source = r->objects->sources; source; source = source->next) { + *path = odb_loose_path(source, &buf, oid); fd = git_open(*path); if (fd >= 0) return fd; @@ -244,11 +244,11 @@ static int open_loose_object(struct repository *r, static int quick_has_loose(struct repository *r, const struct object_id *oid) { - struct object_directory *odb; + struct odb_source *source; prepare_alt_odb(r); - for (odb = r->objects->odb; odb; odb = odb->next) { - if (oidtree_contains(odb_loose_cache(odb, oid), oid)) + for (source = r->objects->sources; source; source = source->next) { + if (oidtree_contains(odb_loose_cache(source, oid), oid)) return 1; } return 0; @@ -694,7 +694,7 @@ void hash_object_file(const struct git_hash_algo *algo, const void *buf, /* Finalize a file on disk, and close it. */ static void close_loose_object(int fd, const char *filename) { - if (the_repository->objects->odb->will_destroy) + if (the_repository->objects->sources->will_destroy) goto out; if (batch_fsync_enabled(FSYNC_COMPONENT_LOOSE_OBJECT)) @@ -876,7 +876,7 @@ static int write_loose_object(const struct object_id *oid, char *hdr, if (batch_fsync_enabled(FSYNC_COMPONENT_LOOSE_OBJECT)) prepare_loose_object_bulk_checkin(); - odb_loose_path(the_repository->objects->odb, &filename, oid); + odb_loose_path(the_repository->objects->sources, &filename, oid); fd = start_loose_object_common(&tmp_file, filename.buf, flags, &stream, compressed, sizeof(compressed), @@ -1023,7 +1023,7 @@ int stream_loose_object(struct input_stream *in_stream, size_t len, goto cleanup; } - odb_loose_path(the_repository->objects->odb, &filename, oid); + odb_loose_path(the_repository->objects->sources, &filename, oid); /* We finally know the object path, and create the missing dir. */ dirlen = directory_size(filename.buf); @@ -1437,11 +1437,11 @@ int for_each_loose_file_in_objdir(const char *path, int for_each_loose_object(each_loose_object_fn cb, void *data, enum for_each_object_flags flags) { - struct object_directory *odb; + struct odb_source *source; prepare_alt_odb(the_repository); - for (odb = the_repository->objects->odb; odb; odb = odb->next) { - int r = for_each_loose_file_in_objdir(odb->path, cb, NULL, + for (source = the_repository->objects->sources; source; source = source->next) { + int r = for_each_loose_file_in_objdir(source->path, cb, NULL, NULL, data); if (r) return r; @@ -1461,43 +1461,43 @@ static int append_loose_object(const struct object_id *oid, return 0; } -struct oidtree *odb_loose_cache(struct object_directory *odb, - const struct object_id *oid) +struct oidtree *odb_loose_cache(struct odb_source *source, + const struct object_id *oid) { int subdir_nr = oid->hash[0]; struct strbuf buf = STRBUF_INIT; - size_t word_bits = bitsizeof(odb->loose_objects_subdir_seen[0]); + size_t word_bits = bitsizeof(source->loose_objects_subdir_seen[0]); size_t word_index = subdir_nr / word_bits; size_t mask = (size_t)1u << (subdir_nr % word_bits); uint32_t *bitmap; if (subdir_nr < 0 || - subdir_nr >= bitsizeof(odb->loose_objects_subdir_seen)) + subdir_nr >= bitsizeof(source->loose_objects_subdir_seen)) BUG("subdir_nr out of range"); - bitmap = &odb->loose_objects_subdir_seen[word_index]; + bitmap = &source->loose_objects_subdir_seen[word_index]; if (*bitmap & mask) - return odb->loose_objects_cache; - if (!odb->loose_objects_cache) { - ALLOC_ARRAY(odb->loose_objects_cache, 1); - oidtree_init(odb->loose_objects_cache); + return source->loose_objects_cache; + if (!source->loose_objects_cache) { + ALLOC_ARRAY(source->loose_objects_cache, 1); + oidtree_init(source->loose_objects_cache); } - strbuf_addstr(&buf, odb->path); + strbuf_addstr(&buf, source->path); for_each_file_in_obj_subdir(subdir_nr, &buf, append_loose_object, NULL, NULL, - odb->loose_objects_cache); + source->loose_objects_cache); *bitmap |= mask; strbuf_release(&buf); - return odb->loose_objects_cache; + return source->loose_objects_cache; } -void odb_clear_loose_cache(struct object_directory *odb) +void odb_clear_loose_cache(struct odb_source *source) { - oidtree_clear(odb->loose_objects_cache); - FREE_AND_NULL(odb->loose_objects_cache); - memset(&odb->loose_objects_subdir_seen, 0, - sizeof(odb->loose_objects_subdir_seen)); + oidtree_clear(source->loose_objects_cache); + FREE_AND_NULL(source->loose_objects_cache); + memset(&source->loose_objects_subdir_seen, 0, + sizeof(source->loose_objects_subdir_seen)); } static int check_stream_oid(git_zstream *stream, diff --git a/object-file.h b/object-file.h index 6f41142452..9a18859b2e 100644 --- a/object-file.h +++ b/object-file.h @@ -24,23 +24,23 @@ enum { int index_fd(struct index_state *istate, struct object_id *oid, int fd, struct stat *st, enum object_type type, const char *path, unsigned flags); int index_path(struct index_state *istate, struct object_id *oid, const char *path, struct stat *st, unsigned flags); -struct object_directory; +struct odb_source; /* * Populate and return the loose object cache array corresponding to the * given object ID. */ -struct oidtree *odb_loose_cache(struct object_directory *odb, +struct oidtree *odb_loose_cache(struct odb_source *source, const struct object_id *oid); /* Empty the loose object cache for the specified object directory. */ -void odb_clear_loose_cache(struct object_directory *odb); +void odb_clear_loose_cache(struct odb_source *source); /* * Put in `buf` the name of the file in the local object database that * would be used to store a loose object with the specified oid. */ -const char *odb_loose_path(struct object_directory *odb, +const char *odb_loose_path(struct odb_source *source, struct strbuf *buf, const struct object_id *oid); diff --git a/object-name.c b/object-name.c index 9288b2dd24..544634d0f4 100644 --- a/object-name.c +++ b/object-name.c @@ -112,10 +112,10 @@ static enum cb_next match_prefix(const struct object_id *oid, void *arg) static void find_short_object_filename(struct disambiguate_state *ds) { - struct object_directory *odb; + struct odb_source *source; - for (odb = ds->repo->objects->odb; odb && !ds->ambiguous; odb = odb->next) - oidtree_each(odb_loose_cache(odb, &ds->bin_pfx), + for (source = ds->repo->objects->sources; source && !ds->ambiguous; source = source->next) + oidtree_each(odb_loose_cache(source, &ds->bin_pfx), &ds->bin_pfx, ds->len, match_prefix, ds); } diff --git a/object-store.c b/object-store.c index f4e8f99d90..5c04a1018f 100644 --- a/object-store.c +++ b/object-store.c @@ -27,7 +27,7 @@ #include "write-or-die.h" KHASH_INIT(odb_path_map, const char * /* key: odb_path */, - struct object_directory *, 1, fspathhash, fspatheq) + struct odb_source *, 1, fspathhash, fspatheq) /* * This is meant to hold a *small* number of objects that you would @@ -104,18 +104,18 @@ static int alt_odb_usable(struct object_database *o, * Prevent the common mistake of listing the same * thing twice, or object directory itself. */ - if (!o->odb_by_path) { + if (!o->source_by_path) { khiter_t p; - o->odb_by_path = kh_init_odb_path_map(); - assert(!o->odb->next); - p = kh_put_odb_path_map(o->odb_by_path, o->odb->path, &r); + o->source_by_path = kh_init_odb_path_map(); + assert(!o->sources->next); + p = kh_put_odb_path_map(o->source_by_path, o->sources->path, &r); assert(r == 1); /* never used */ - kh_value(o->odb_by_path, p) = o->odb; + kh_value(o->source_by_path, p) = o->sources; } if (fspatheq(path->buf, normalized_objdir)) return 0; - *pos = kh_put_odb_path_map(o->odb_by_path, path->buf, &r); + *pos = kh_put_odb_path_map(o->source_by_path, path->buf, &r); /* r: 0 = exists, 1 = never used, 2 = deleted */ return r == 0 ? 0 : 1; } @@ -124,7 +124,7 @@ static int alt_odb_usable(struct object_database *o, * Prepare alternate object database registry. * * The variable alt_odb_list points at the list of struct - * object_directory. The elements on this list come from + * odb_source. The elements on this list come from * non-empty elements from colon separated ALTERNATE_DB_ENVIRONMENT * environment variable, and $GIT_OBJECT_DIRECTORY/info/alternates, * whose contents is similar to that environment variable but can be @@ -141,7 +141,7 @@ static void read_info_alternates(struct repository *r, static int link_alt_odb_entry(struct repository *r, const struct strbuf *entry, const char *relative_base, int depth, const char *normalized_objdir) { - struct object_directory *ent; + struct odb_source *alternate; struct strbuf pathbuf = STRBUF_INIT; struct strbuf tmp = STRBUF_INIT; khiter_t pos; @@ -170,19 +170,19 @@ static int link_alt_odb_entry(struct repository *r, const struct strbuf *entry, if (!alt_odb_usable(r->objects, &pathbuf, normalized_objdir, &pos)) goto error; - CALLOC_ARRAY(ent, 1); - /* pathbuf.buf is already in r->objects->odb_by_path */ - ent->path = strbuf_detach(&pathbuf, NULL); + CALLOC_ARRAY(alternate, 1); + /* pathbuf.buf is already in r->objects->source_by_path */ + alternate->path = strbuf_detach(&pathbuf, NULL); /* add the alternate entry */ - *r->objects->odb_tail = ent; - r->objects->odb_tail = &(ent->next); - ent->next = NULL; - assert(r->objects->odb_by_path); - kh_value(r->objects->odb_by_path, pos) = ent; + *r->objects->sources_tail = alternate; + r->objects->sources_tail = &(alternate->next); + alternate->next = NULL; + assert(r->objects->source_by_path); + kh_value(r->objects->source_by_path, pos) = alternate; /* recursively add alternates */ - read_info_alternates(r, ent->path, depth + 1); + read_info_alternates(r, alternate->path, depth + 1); ret = 0; error: strbuf_release(&tmp); @@ -234,7 +234,7 @@ static void link_alt_odb_entries(struct repository *r, const char *alt, return; } - strbuf_realpath(&objdirbuf, r->objects->odb->path, 1); + strbuf_realpath(&objdirbuf, r->objects->sources->path, 1); while (*alt) { alt = parse_alt_odb_entry(alt, sep, &entry); @@ -321,9 +321,9 @@ void add_to_alternates_memory(const char *reference) '\n', NULL, 0); } -struct object_directory *set_temporary_primary_odb(const char *dir, int will_destroy) +struct odb_source *set_temporary_primary_odb(const char *dir, int will_destroy) { - struct object_directory *new_odb; + struct odb_source *source; /* * Make sure alternates are initialized, or else our entry may be @@ -335,41 +335,41 @@ struct object_directory *set_temporary_primary_odb(const char *dir, int will_des * Make a new primary odb and link the old primary ODB in as an * alternate */ - new_odb = xcalloc(1, sizeof(*new_odb)); - new_odb->path = xstrdup(dir); + source = xcalloc(1, sizeof(*source)); + source->path = xstrdup(dir); /* * Disable ref updates while a temporary odb is active, since * the objects in the database may roll back. */ - new_odb->disable_ref_updates = 1; - new_odb->will_destroy = will_destroy; - new_odb->next = the_repository->objects->odb; - the_repository->objects->odb = new_odb; - return new_odb->next; + source->disable_ref_updates = 1; + source->will_destroy = will_destroy; + source->next = the_repository->objects->sources; + the_repository->objects->sources = source; + return source->next; } -static void free_object_directory(struct object_directory *odb) +static void free_object_directory(struct odb_source *source) { - free(odb->path); - odb_clear_loose_cache(odb); - loose_object_map_clear(&odb->loose_map); - free(odb); + free(source->path); + odb_clear_loose_cache(source); + loose_object_map_clear(&source->loose_map); + free(source); } -void restore_primary_odb(struct object_directory *restore_odb, const char *old_path) +void restore_primary_odb(struct odb_source *restore_alt, const char *old_path) { - struct object_directory *cur_odb = the_repository->objects->odb; + struct odb_source *cur_alt = the_repository->objects->sources; - if (strcmp(old_path, cur_odb->path)) + if (strcmp(old_path, cur_alt->path)) BUG("expected %s as primary object store; found %s", - old_path, cur_odb->path); + old_path, cur_alt->path); - if (cur_odb->next != restore_odb) + if (cur_alt->next != restore_alt) BUG("we expect the old primary object store to be the first alternate"); - the_repository->objects->odb = restore_odb; - free_object_directory(cur_odb); + the_repository->objects->sources = restore_alt; + free_object_directory(cur_alt); } /* @@ -442,15 +442,15 @@ out: return ref_git; } -struct object_directory *find_odb(struct repository *r, const char *obj_dir) +struct odb_source *find_odb(struct repository *r, const char *obj_dir) { - struct object_directory *odb; + struct odb_source *source; char *obj_dir_real = real_pathdup(obj_dir, 1); struct strbuf odb_path_real = STRBUF_INIT; prepare_alt_odb(r); - for (odb = r->objects->odb; odb; odb = odb->next) { - strbuf_realpath(&odb_path_real, odb->path, 1); + for (source = r->objects->sources; source; source = source->next) { + strbuf_realpath(&odb_path_real, source->path, 1); if (!strcmp(obj_dir_real, odb_path_real.buf)) break; } @@ -458,9 +458,9 @@ struct object_directory *find_odb(struct repository *r, const char *obj_dir) free(obj_dir_real); strbuf_release(&odb_path_real); - if (!odb) + if (!source) die(_("could not find object directory matching %s"), obj_dir); - return odb; + return source; } static void fill_alternate_refs_command(struct child_process *cmd, @@ -527,14 +527,14 @@ struct alternate_refs_data { void *data; }; -static int refs_from_alternate_cb(struct object_directory *e, +static int refs_from_alternate_cb(struct odb_source *alternate, void *data) { struct strbuf path = STRBUF_INIT; size_t base_len; struct alternate_refs_data *cb = data; - if (!strbuf_realpath(&path, e->path, 0)) + if (!strbuf_realpath(&path, alternate->path, 0)) goto out; if (!strbuf_strip_suffix(&path, "/objects")) goto out; @@ -563,12 +563,12 @@ void for_each_alternate_ref(alternate_ref_fn fn, void *data) int foreach_alt_odb(alt_odb_fn fn, void *cb) { - struct object_directory *ent; + struct odb_source *alternate; int r = 0; prepare_alt_odb(the_repository); - for (ent = the_repository->objects->odb->next; ent; ent = ent->next) { - r = fn(ent, cb); + for (alternate = the_repository->objects->sources->next; alternate; alternate = alternate->next) { + r = fn(alternate, cb); if (r) break; } @@ -582,14 +582,14 @@ void prepare_alt_odb(struct repository *r) link_alt_odb_entries(r, r->objects->alternate_db, PATH_SEP, NULL, 0); - read_info_alternates(r, r->objects->odb->path, 0); + read_info_alternates(r, r->objects->sources->path, 0); r->objects->loaded_alternates = 1; } int has_alt_odb(struct repository *r) { prepare_alt_odb(r); - return !!r->objects->odb->next; + return !!r->objects->sources->next; } int obj_read_use_lock = 0; @@ -963,15 +963,15 @@ struct object_database *odb_new(void) static void free_object_directories(struct object_database *o) { - while (o->odb) { - struct object_directory *next; + while (o->sources) { + struct odb_source *next; - next = o->odb->next; - free_object_directory(o->odb); - o->odb = next; + next = o->sources->next; + free_object_directory(o->sources); + o->sources = next; } - kh_destroy_odb_path_map(o->odb_by_path); - o->odb_by_path = NULL; + kh_destroy_odb_path_map(o->source_by_path); + o->source_by_path = NULL; } void odb_clear(struct object_database *o) @@ -986,7 +986,7 @@ void odb_clear(struct object_database *o) o->commit_graph_attempted = 0; free_object_directories(o); - o->odb_tail = NULL; + o->sources_tail = NULL; o->loaded_alternates = 0; for (size_t i = 0; i < o->cached_object_nr; i++) diff --git a/object-store.h b/object-store.h index a3be27d117..d199d757d7 100644 --- a/object-store.h +++ b/object-store.h @@ -13,8 +13,20 @@ struct oidtree; struct strbuf; struct repository; -struct object_directory { - struct object_directory *next; +/* + * The source is the part of the object database that stores the actual + * objects. It thus encapsulates the logic to read and write the specific + * on-disk format. An object database can have multiple sources: + * + * - The primary source, which is typically located in "$GIT_DIR/objects". + * This is where new objects are usually written to. + * + * - Alternate sources, which are configured via "objects/info/alternates" or + * via the GIT_ALTERNATE_OBJECT_DIRECTORIES environment variable. These + * alternate sources are only used to read objects. + */ +struct odb_source { + struct odb_source *next; /* * Used to store the results of readdir(3) calls when we are OK @@ -44,8 +56,8 @@ struct object_directory { int will_destroy; /* - * Path to the alternative object store. If this is a relative path, - * it is relative to the current working directory. + * Path to the source. If this is a relative path, it is relative to + * the current working directory. */ char *path; }; @@ -53,8 +65,8 @@ struct object_directory { void prepare_alt_odb(struct repository *r); int has_alt_odb(struct repository *r); char *compute_alternate_path(const char *path, struct strbuf *err); -struct object_directory *find_odb(struct repository *r, const char *obj_dir); -typedef int alt_odb_fn(struct object_directory *, void *); +struct odb_source *find_odb(struct repository *r, const char *obj_dir); +typedef int alt_odb_fn(struct odb_source *, void *); int foreach_alt_odb(alt_odb_fn, void*); typedef void alternate_ref_fn(const struct object_id *oid, void *); void for_each_alternate_ref(alternate_ref_fn, void *); @@ -76,12 +88,12 @@ void add_to_alternates_memory(const char *dir); * Replace the current writable object directory with the specified temporary * object directory; returns the former primary object directory. */ -struct object_directory *set_temporary_primary_odb(const char *dir, int will_destroy); +struct odb_source *set_temporary_primary_odb(const char *dir, int will_destroy); /* * Restore a previous ODB replaced by set_temporary_main_odb. */ -void restore_primary_odb(struct object_directory *restore_odb, const char *old_path); +void restore_primary_odb(struct odb_source *restore_alternate, const char *old_path); struct packed_git; struct multi_pack_index; @@ -89,7 +101,7 @@ struct cached_object_entry; /* * The object database encapsulates access to objects in a repository. It - * manages one or more backends that store the actual objects which are + * manages one or more sources that store the actual objects which are * configured via alternates. */ struct object_database { @@ -98,16 +110,16 @@ struct object_database { * cannot be NULL after initialization). Subsequent directories are * alternates. */ - struct object_directory *odb; - struct object_directory **odb_tail; - struct kh_odb_path_map *odb_by_path; + struct odb_source *sources; + struct odb_source **sources_tail; + struct kh_odb_path_map *source_by_path; int loaded_alternates; /* * A list of alternate object directories loaded from the environment; * this should not generally need to be accessed directly, but will - * populate the "odb" list when prepare_alt_odb() is run. + * populate the "sources" list when prepare_alt_odb() is run. */ char *alternate_db; diff --git a/packfile.c b/packfile.c index c735b4d013..60661ad009 100644 --- a/packfile.c +++ b/packfile.c @@ -1029,16 +1029,16 @@ static void prepare_packed_git_mru(struct repository *r) static void prepare_packed_git(struct repository *r) { - struct object_directory *odb; + struct odb_source *source; if (r->objects->packed_git_initialized) return; prepare_alt_odb(r); - for (odb = r->objects->odb; odb; odb = odb->next) { - int local = (odb == r->objects->odb); - prepare_multi_pack_index_one(r, odb->path, local); - prepare_packed_git_one(r, odb->path, local); + for (source = r->objects->sources; source; source = source->next) { + int local = (source == r->objects->sources); + prepare_multi_pack_index_one(r, source->path, local); + prepare_packed_git_one(r, source->path, local); } rearrange_packed_git(r); @@ -1048,7 +1048,7 @@ static void prepare_packed_git(struct repository *r) void reprepare_packed_git(struct repository *r) { - struct object_directory *odb; + struct odb_source *source; obj_read_lock(); @@ -1061,8 +1061,8 @@ void reprepare_packed_git(struct repository *r) r->objects->loaded_alternates = 0; prepare_alt_odb(r); - for (odb = r->objects->odb; odb; odb = odb->next) - odb_clear_loose_cache(odb); + for (source = r->objects->sources; source; source = source->next) + odb_clear_loose_cache(source); r->objects->approximate_object_count_valid = 0; r->objects->packed_git_initialized = 0; diff --git a/path.c b/path.c index 3b598b2847..c347829aa6 100644 --- a/path.c +++ b/path.c @@ -397,7 +397,7 @@ static void adjust_git_path(struct repository *repo, strbuf_splice(buf, 0, buf->len, repo->index_file, strlen(repo->index_file)); else if (dir_prefix(base, "objects")) - replace_dir(buf, git_dir_len + 7, repo->objects->odb->path); + replace_dir(buf, git_dir_len + 7, repo->objects->sources->path); else if (repo_settings_get_hooks_path(repo) && dir_prefix(base, "hooks")) replace_dir(buf, git_dir_len + 5, repo_settings_get_hooks_path(repo)); else if (repo->different_commondir) diff --git a/refs.c b/refs.c index dce5c49ca2..5f6a386cc9 100644 --- a/refs.c +++ b/refs.c @@ -2477,7 +2477,7 @@ int ref_transaction_prepare(struct ref_transaction *transaction, break; } - if (refs->repo->objects->odb->disable_ref_updates) { + if (refs->repo->objects->sources->disable_ref_updates) { strbuf_addstr(err, _("ref updates forbidden inside quarantine environment")); return -1; diff --git a/repository.c b/repository.c index 07757e6e0c..7528beccdd 100644 --- a/repository.c +++ b/repository.c @@ -107,9 +107,9 @@ const char *repo_get_common_dir(struct repository *repo) const char *repo_get_object_directory(struct repository *repo) { - if (!repo->objects->odb) + if (!repo->objects->sources) BUG("repository hasn't been set up"); - return repo->objects->odb->path; + return repo->objects->sources->path; } const char *repo_get_index_file(struct repository *repo) @@ -165,14 +165,14 @@ void repo_set_gitdir(struct repository *repo, repo_set_commondir(repo, o->commondir); - if (!repo->objects->odb) { - CALLOC_ARRAY(repo->objects->odb, 1); - repo->objects->odb_tail = &repo->objects->odb->next; + if (!repo->objects->sources) { + CALLOC_ARRAY(repo->objects->sources, 1); + repo->objects->sources_tail = &repo->objects->sources->next; } - expand_base_dir(&repo->objects->odb->path, o->object_dir, + expand_base_dir(&repo->objects->sources->path, o->object_dir, repo->commondir, "objects"); - repo->objects->odb->disable_ref_updates = o->disable_ref_updates; + repo->objects->sources->disable_ref_updates = o->disable_ref_updates; free(repo->objects->alternate_db); repo->objects->alternate_db = xstrdup_or_null(o->alternate_db); diff --git a/submodule-config.c b/submodule-config.c index 8630e27947..b30d9365fb 100644 --- a/submodule-config.c +++ b/submodule-config.c @@ -810,7 +810,7 @@ static void config_from_gitmodules(config_fn_t fn, struct repository *repo, void repo_get_oid(repo, GITMODULES_HEAD, &oid) >= 0) { config_source.blob = oidstr = xstrdup(oid_to_hex(&oid)); if (repo != the_repository) - add_submodule_odb_by_path(repo->objects->odb->path); + add_submodule_odb_by_path(repo->objects->sources->path); } else { goto out; } diff --git a/t/helper/test-read-graph.c b/t/helper/test-read-graph.c index 8b413b644b..53b633e2ba 100644 --- a/t/helper/test-read-graph.c +++ b/t/helper/test-read-graph.c @@ -73,15 +73,15 @@ static void dump_graph_bloom_filters(struct commit_graph *graph) int cmd__read_graph(int argc, const char **argv) { struct commit_graph *graph = NULL; - struct object_directory *odb; + struct odb_source *source; int ret = 0; setup_git_directory(); - odb = the_repository->objects->odb; + source = the_repository->objects->sources; prepare_repo_settings(the_repository); - graph = read_commit_graph_one(the_repository, odb); + graph = read_commit_graph_one(the_repository, source); if (!graph) { ret = 1; goto done; diff --git a/tmp-objdir.c b/tmp-objdir.c index c38fbeb5e8..056484404b 100644 --- a/tmp-objdir.c +++ b/tmp-objdir.c @@ -17,7 +17,7 @@ struct tmp_objdir { struct repository *repo; struct strbuf path; struct strvec env; - struct object_directory *prev_odb; + struct odb_source *prev_source; int will_destroy; }; @@ -46,8 +46,8 @@ int tmp_objdir_destroy(struct tmp_objdir *t) if (t == the_tmp_objdir) the_tmp_objdir = NULL; - if (t->prev_odb) - restore_primary_odb(t->prev_odb, t->path.buf); + if (t->prev_source) + restore_primary_odb(t->prev_source, t->path.buf); err = remove_dir_recursively(&t->path, 0); @@ -276,11 +276,11 @@ int tmp_objdir_migrate(struct tmp_objdir *t) if (!t) return 0; - if (t->prev_odb) { - if (t->repo->objects->odb->will_destroy) + if (t->prev_source) { + if (t->repo->objects->sources->will_destroy) BUG("migrating an ODB that was marked for destruction"); - restore_primary_odb(t->prev_odb, t->path.buf); - t->prev_odb = NULL; + restore_primary_odb(t->prev_source, t->path.buf); + t->prev_source = NULL; } strbuf_addbuf(&src, &t->path); @@ -309,19 +309,19 @@ void tmp_objdir_add_as_alternate(const struct tmp_objdir *t) void tmp_objdir_replace_primary_odb(struct tmp_objdir *t, int will_destroy) { - if (t->prev_odb) + if (t->prev_source) BUG("the primary object database is already replaced"); - t->prev_odb = set_temporary_primary_odb(t->path.buf, will_destroy); + t->prev_source = set_temporary_primary_odb(t->path.buf, will_destroy); t->will_destroy = will_destroy; } struct tmp_objdir *tmp_objdir_unapply_primary_odb(void) { - if (!the_tmp_objdir || !the_tmp_objdir->prev_odb) + if (!the_tmp_objdir || !the_tmp_objdir->prev_source) return NULL; - restore_primary_odb(the_tmp_objdir->prev_odb, the_tmp_objdir->path.buf); - the_tmp_objdir->prev_odb = NULL; + restore_primary_odb(the_tmp_objdir->prev_source, the_tmp_objdir->path.buf); + the_tmp_objdir->prev_source = NULL; return the_tmp_objdir; } -- cgit v1.2.3 From 8f49151763cb81adf4bcec53c1ae67057081b02d Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Tue, 1 Jul 2025 14:22:15 +0200 Subject: object-store: rename files to "odb.{c,h}" In the preceding commits we have renamed the structures contained in "object-store.h" to `struct object_database` and `struct odb_backend`. As such, the code files "object-store.{c,h}" are confusingly named now. Rename them to "odb.{c,h}" accordingly. Signed-off-by: Patrick Steinhardt Signed-off-by: Junio C Hamano --- Makefile | 2 +- apply.c | 2 +- archive-tar.c | 2 +- archive-zip.c | 2 +- archive.c | 2 +- attr.c | 2 +- bisect.c | 2 +- blame.c | 2 +- builtin/backfill.c | 2 +- builtin/blame.c | 2 +- builtin/cat-file.c | 2 +- builtin/checkout.c | 2 +- builtin/clone.c | 2 +- builtin/commit-graph.c | 2 +- builtin/commit-tree.c | 2 +- builtin/describe.c | 2 +- builtin/difftool.c | 2 +- builtin/fast-export.c | 2 +- builtin/fast-import.c | 2 +- builtin/fetch.c | 2 +- builtin/fsck.c | 2 +- builtin/grep.c | 2 +- builtin/hash-object.c | 2 +- builtin/index-pack.c | 2 +- builtin/log.c | 2 +- builtin/ls-files.c | 2 +- builtin/ls-tree.c | 2 +- builtin/merge-file.c | 2 +- builtin/merge-tree.c | 2 +- builtin/mktag.c | 2 +- builtin/mktree.c | 2 +- builtin/multi-pack-index.c | 2 +- builtin/notes.c | 2 +- builtin/pack-objects.c | 2 +- builtin/pack-redundant.c | 2 +- builtin/prune.c | 2 +- builtin/receive-pack.c | 2 +- builtin/remote.c | 2 +- builtin/repack.c | 2 +- builtin/replace.c | 2 +- builtin/rev-list.c | 2 +- builtin/show-ref.c | 2 +- builtin/submodule--helper.c | 2 +- builtin/tag.c | 2 +- builtin/unpack-file.c | 2 +- builtin/unpack-objects.c | 2 +- bulk-checkin.c | 2 +- bundle-uri.c | 2 +- bundle.c | 2 +- cache-tree.c | 2 +- combine-diff.c | 2 +- commit-graph.c | 2 +- commit-graph.h | 2 +- commit.c | 2 +- config.c | 2 +- connected.c | 2 +- contrib/coccinelle/the_repository.cocci | 2 +- diagnose.c | 2 +- diff.c | 2 +- entry.c | 2 +- fetch-pack.c | 2 +- fmt-merge-msg.c | 2 +- fsck.c | 2 +- grep.c | 2 +- http-backend.c | 2 +- http-push.c | 2 +- http-walker.c | 2 +- http.c | 2 +- list-objects-filter.c | 2 +- list-objects.c | 2 +- loose.c | 2 +- mailmap.c | 2 +- match-trees.c | 2 +- merge-blobs.c | 2 +- merge-ort.c | 2 +- meson.build | 2 +- notes-cache.c | 2 +- notes-merge.c | 2 +- notes.c | 2 +- object-file.c | 2 +- object-file.h | 2 +- object-store.c | 1010 ------------------------------- object-store.h | 355 ----------- odb.c | 1010 +++++++++++++++++++++++++++++++ odb.h | 355 +++++++++++ oss-fuzz/fuzz-pack-idx.c | 2 +- pack-bitmap-write.c | 2 +- pack-bitmap.c | 2 +- pack-check.c | 2 +- pack-mtimes.c | 2 +- pack-objects.h | 2 +- pack-revindex.c | 2 +- packfile.c | 2 +- packfile.h | 4 +- path.c | 2 +- promisor-remote.c | 2 +- protocol-caps.c | 2 +- read-cache.c | 2 +- ref-filter.c | 2 +- reflog.c | 2 +- refs.c | 2 +- remote.c | 2 +- replace-object.c | 2 +- replace-object.h | 2 +- repository.c | 2 +- rerere.c | 2 +- revision.c | 2 +- send-pack.c | 2 +- sequencer.c | 2 +- server-info.c | 2 +- shallow.c | 2 +- streaming.c | 2 +- submodule-config.c | 2 +- submodule.c | 2 +- t/helper/test-find-pack.c | 2 +- t/helper/test-pack-mtimes.c | 2 +- t/helper/test-partial-clone.c | 2 +- t/helper/test-read-graph.c | 2 +- t/helper/test-read-midx.c | 2 +- t/helper/test-ref-store.c | 2 +- tag.c | 2 +- tmp-objdir.c | 2 +- tree-walk.c | 2 +- tree.c | 2 +- unpack-trees.c | 2 +- upload-pack.c | 2 +- walker.c | 2 +- xdiff-interface.c | 2 +- 128 files changed, 1490 insertions(+), 1490 deletions(-) delete mode 100644 object-store.c delete mode 100644 object-store.h create mode 100644 odb.c create mode 100644 odb.h (limited to 'commit-graph.h') diff --git a/Makefile b/Makefile index 70d1543b6b..4b1bf89779 100644 --- a/Makefile +++ b/Makefile @@ -1085,8 +1085,8 @@ LIB_OBJS += notes.o LIB_OBJS += object-file-convert.o LIB_OBJS += object-file.o LIB_OBJS += object-name.o -LIB_OBJS += object-store.o LIB_OBJS += object.o +LIB_OBJS += odb.o LIB_OBJS += oid-array.o LIB_OBJS += oidmap.o LIB_OBJS += oidset.o diff --git a/apply.c b/apply.c index 8bbe6ed224..e778b4e911 100644 --- a/apply.c +++ b/apply.c @@ -14,7 +14,7 @@ #include "abspath.h" #include "base85.h" #include "config.h" -#include "object-store.h" +#include "odb.h" #include "delta.h" #include "diff.h" #include "dir.h" diff --git a/archive-tar.c b/archive-tar.c index 282b48196f..249164ea77 100644 --- a/archive-tar.c +++ b/archive-tar.c @@ -11,7 +11,7 @@ #include "hex.h" #include "tar.h" #include "archive.h" -#include "object-store.h" +#include "odb.h" #include "strbuf.h" #include "streaming.h" #include "run-command.h" diff --git a/archive-zip.c b/archive-zip.c index 405da6f3d8..df8866d5ba 100644 --- a/archive-zip.c +++ b/archive-zip.c @@ -12,7 +12,7 @@ #include "hex.h" #include "streaming.h" #include "utf8.h" -#include "object-store.h" +#include "odb.h" #include "strbuf.h" #include "userdiff.h" #include "write-or-die.h" diff --git a/archive.c b/archive.c index 8309ea213e..7fa2cc2596 100644 --- a/archive.c +++ b/archive.c @@ -14,7 +14,7 @@ #include "pretty.h" #include "setup.h" #include "refs.h" -#include "object-store.h" +#include "odb.h" #include "commit.h" #include "tree.h" #include "tree-walk.h" diff --git a/attr.c b/attr.c index 86b6109fc4..e5680db7f6 100644 --- a/attr.c +++ b/attr.c @@ -22,7 +22,7 @@ #include "read-cache-ll.h" #include "refs.h" #include "revision.h" -#include "object-store.h" +#include "odb.h" #include "setup.h" #include "thread-utils.h" #include "tree-walk.h" diff --git a/bisect.c b/bisect.c index a327468c75..a7939216d0 100644 --- a/bisect.c +++ b/bisect.c @@ -20,7 +20,7 @@ #include "commit-slab.h" #include "commit-reach.h" #include "object-name.h" -#include "object-store.h" +#include "odb.h" #include "path.h" #include "dir.h" diff --git a/blame.c b/blame.c index 57daa45e89..0ceea080a8 100644 --- a/blame.c +++ b/blame.c @@ -3,7 +3,7 @@ #include "git-compat-util.h" #include "refs.h" -#include "object-store.h" +#include "odb.h" #include "cache-tree.h" #include "mergesort.h" #include "commit.h" diff --git a/builtin/backfill.c b/builtin/backfill.c index fa82ad2f6f..0b49baa39f 100644 --- a/builtin/backfill.c +++ b/builtin/backfill.c @@ -13,7 +13,7 @@ #include "tree.h" #include "tree-walk.h" #include "object.h" -#include "object-store.h" +#include "odb.h" #include "oid-array.h" #include "oidset.h" #include "promisor-remote.h" diff --git a/builtin/blame.c b/builtin/blame.c index 944952e30e..15eda60af9 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -28,7 +28,7 @@ #include "line-log.h" #include "progress.h" #include "object-name.h" -#include "object-store.h" +#include "odb.h" #include "pager.h" #include "blame.h" #include "refs.h" diff --git a/builtin/cat-file.c b/builtin/cat-file.c index 67a5ff2b9e..f3a925a818 100644 --- a/builtin/cat-file.c +++ b/builtin/cat-file.c @@ -24,7 +24,7 @@ #include "pack-bitmap.h" #include "object-file.h" #include "object-name.h" -#include "object-store.h" +#include "odb.h" #include "replace-object.h" #include "promisor-remote.h" #include "mailmap.h" diff --git a/builtin/checkout.c b/builtin/checkout.c index d185982f3a..e7dd66173d 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -20,7 +20,7 @@ #include "merge-ort-wrappers.h" #include "object-file.h" #include "object-name.h" -#include "object-store.h" +#include "odb.h" #include "parse-options.h" #include "path.h" #include "preload-index.h" diff --git a/builtin/clone.c b/builtin/clone.c index 91b9cd0d16..1eafeefb48 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -25,7 +25,7 @@ #include "refs.h" #include "refspec.h" #include "object-file.h" -#include "object-store.h" +#include "odb.h" #include "tree.h" #include "tree-walk.h" #include "unpack-trees.h" diff --git a/builtin/commit-graph.c b/builtin/commit-graph.c index 98a8431534..f04eaba525 100644 --- a/builtin/commit-graph.c +++ b/builtin/commit-graph.c @@ -6,7 +6,7 @@ #include "hex.h" #include "parse-options.h" #include "commit-graph.h" -#include "object-store.h" +#include "odb.h" #include "progress.h" #include "replace-object.h" #include "strbuf.h" diff --git a/builtin/commit-tree.c b/builtin/commit-tree.c index ad6b2c9320..546069f868 100644 --- a/builtin/commit-tree.c +++ b/builtin/commit-tree.c @@ -9,7 +9,7 @@ #include "gettext.h" #include "hex.h" #include "object-name.h" -#include "object-store.h" +#include "odb.h" #include "commit.h" #include "parse-options.h" diff --git a/builtin/describe.c b/builtin/describe.c index 2d50883b72..96cb68e5e5 100644 --- a/builtin/describe.c +++ b/builtin/describe.c @@ -19,7 +19,7 @@ #include "setup.h" #include "strvec.h" #include "run-command.h" -#include "object-store.h" +#include "odb.h" #include "list-objects.h" #include "commit-slab.h" #include "wildmatch.h" diff --git a/builtin/difftool.c b/builtin/difftool.c index a3b64ce694..fac613e3bc 100644 --- a/builtin/difftool.c +++ b/builtin/difftool.c @@ -30,7 +30,7 @@ #include "strbuf.h" #include "lockfile.h" #include "object-file.h" -#include "object-store.h" +#include "odb.h" #include "dir.h" #include "entry.h" #include "setup.h" diff --git a/builtin/fast-export.c b/builtin/fast-export.c index 37c01d6c6f..0505f289a9 100644 --- a/builtin/fast-export.c +++ b/builtin/fast-export.c @@ -14,7 +14,7 @@ #include "refs.h" #include "refspec.h" #include "object-file.h" -#include "object-store.h" +#include "odb.h" #include "commit.h" #include "object.h" #include "tag.h" diff --git a/builtin/fast-import.c b/builtin/fast-import.c index b2839c5f43..52c792488e 100644 --- a/builtin/fast-import.c +++ b/builtin/fast-import.c @@ -24,7 +24,7 @@ #include "packfile.h" #include "object-file.h" #include "object-name.h" -#include "object-store.h" +#include "odb.h" #include "mem-pool.h" #include "commit-reach.h" #include "khash.h" diff --git a/builtin/fetch.c b/builtin/fetch.c index a890e2864d..b842bc9c51 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -14,7 +14,7 @@ #include "refs.h" #include "refspec.h" #include "object-name.h" -#include "object-store.h" +#include "odb.h" #include "oidset.h" #include "oid-array.h" #include "commit.h" diff --git a/builtin/fsck.c b/builtin/fsck.c index 6e1474f63d..9abd7b2558 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -17,7 +17,7 @@ #include "packfile.h" #include "object-file.h" #include "object-name.h" -#include "object-store.h" +#include "odb.h" #include "path.h" #include "read-cache-ll.h" #include "replace-object.h" diff --git a/builtin/grep.c b/builtin/grep.c index 76b1938bba..a1d7ee7af3 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -26,7 +26,7 @@ #include "submodule-config.h" #include "object-file.h" #include "object-name.h" -#include "object-store.h" +#include "odb.h" #include "packfile.h" #include "pager.h" #include "path.h" diff --git a/builtin/hash-object.c b/builtin/hash-object.c index 6a99ec250d..e28f000221 100644 --- a/builtin/hash-object.c +++ b/builtin/hash-object.c @@ -11,7 +11,7 @@ #include "gettext.h" #include "hex.h" #include "object-file.h" -#include "object-store.h" +#include "odb.h" #include "blob.h" #include "quote.h" #include "parse-options.h" diff --git a/builtin/index-pack.c b/builtin/index-pack.c index bb7925bd29..1aabe6b8ee 100644 --- a/builtin/index-pack.c +++ b/builtin/index-pack.c @@ -21,7 +21,7 @@ #include "packfile.h" #include "pack-revindex.h" #include "object-file.h" -#include "object-store.h" +#include "odb.h" #include "oid-array.h" #include "oidset.h" #include "path.h" diff --git a/builtin/log.c b/builtin/log.c index b450cd3bde..fe9cc5ebec 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -15,7 +15,7 @@ #include "hex.h" #include "refs.h" #include "object-name.h" -#include "object-store.h" +#include "odb.h" #include "pager.h" #include "color.h" #include "commit.h" diff --git a/builtin/ls-files.c b/builtin/ls-files.c index be74f0a03b..821339b07d 100644 --- a/builtin/ls-files.c +++ b/builtin/ls-files.c @@ -25,7 +25,7 @@ #include "setup.h" #include "sparse-index.h" #include "submodule.h" -#include "object-store.h" +#include "odb.h" #include "hex.h" diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c index 8aafc30ca4..62b6fd58c1 100644 --- a/builtin/ls-tree.c +++ b/builtin/ls-tree.c @@ -10,7 +10,7 @@ #include "gettext.h" #include "hex.h" #include "object-name.h" -#include "object-store.h" +#include "odb.h" #include "tree.h" #include "path.h" #include "quote.h" diff --git a/builtin/merge-file.c b/builtin/merge-file.c index 2b16b10d2c..9464f27562 100644 --- a/builtin/merge-file.c +++ b/builtin/merge-file.c @@ -7,7 +7,7 @@ #include "hex.h" #include "object-file.h" #include "object-name.h" -#include "object-store.h" +#include "odb.h" #include "config.h" #include "gettext.h" #include "setup.h" diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c index 7f41665dfd..b1a17787bc 100644 --- a/builtin/merge-tree.c +++ b/builtin/merge-tree.c @@ -10,7 +10,7 @@ #include "commit-reach.h" #include "merge-ort.h" #include "object-name.h" -#include "object-store.h" +#include "odb.h" #include "parse-options.h" #include "blob.h" #include "merge-blobs.h" diff --git a/builtin/mktag.c b/builtin/mktag.c index 7ac11c46d5..1809b38f93 100644 --- a/builtin/mktag.c +++ b/builtin/mktag.c @@ -6,7 +6,7 @@ #include "strbuf.h" #include "replace-object.h" #include "object-file.h" -#include "object-store.h" +#include "odb.h" #include "fsck.h" #include "config.h" diff --git a/builtin/mktree.c b/builtin/mktree.c index 4b47803467..016b0e5b22 100644 --- a/builtin/mktree.c +++ b/builtin/mktree.c @@ -12,7 +12,7 @@ #include "tree.h" #include "parse-options.h" #include "object-file.h" -#include "object-store.h" +#include "odb.h" static struct treeent { unsigned mode; diff --git a/builtin/multi-pack-index.c b/builtin/multi-pack-index.c index f55bf53da8..aa25b06f9d 100644 --- a/builtin/multi-pack-index.c +++ b/builtin/multi-pack-index.c @@ -7,7 +7,7 @@ #include "midx.h" #include "strbuf.h" #include "trace2.h" -#include "object-store.h" +#include "odb.h" #include "replace-object.h" #include "repository.h" diff --git a/builtin/notes.c b/builtin/notes.c index a3f433ca4c..783d4932ca 100644 --- a/builtin/notes.c +++ b/builtin/notes.c @@ -16,7 +16,7 @@ #include "notes.h" #include "object-file.h" #include "object-name.h" -#include "object-store.h" +#include "odb.h" #include "path.h" #include "pretty.h" diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index 8b33edc2ff..99b63cb098 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -32,7 +32,7 @@ #include "list.h" #include "packfile.h" #include "object-file.h" -#include "object-store.h" +#include "odb.h" #include "replace-object.h" #include "dir.h" #include "midx.h" diff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c index 5d1fc78176..3134cb8c68 100644 --- a/builtin/pack-redundant.c +++ b/builtin/pack-redundant.c @@ -13,7 +13,7 @@ #include "hex.h" #include "packfile.h" -#include "object-store.h" +#include "odb.h" #include "strbuf.h" #define BLKSIZE 512 diff --git a/builtin/prune.c b/builtin/prune.c index e930caa0c0..7bbfb14c2b 100644 --- a/builtin/prune.c +++ b/builtin/prune.c @@ -17,7 +17,7 @@ #include "replace-object.h" #include "object-file.h" #include "object-name.h" -#include "object-store.h" +#include "odb.h" #include "shallow.h" static const char * const prune_usage[] = { diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index a317d6c278..0f5958c4a6 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -33,7 +33,7 @@ #include "packfile.h" #include "object-file.h" #include "object-name.h" -#include "object-store.h" +#include "odb.h" #include "path.h" #include "protocol.h" #include "commit-reach.h" diff --git a/builtin/remote.c b/builtin/remote.c index 0d6755bcb7..ac5b8d2a1a 100644 --- a/builtin/remote.c +++ b/builtin/remote.c @@ -14,7 +14,7 @@ #include "rebase.h" #include "refs.h" #include "refspec.h" -#include "object-store.h" +#include "odb.h" #include "strvec.h" #include "commit-reach.h" #include "progress.h" diff --git a/builtin/repack.c b/builtin/repack.c index 59214dbdfd..1678232005 100644 --- a/builtin/repack.c +++ b/builtin/repack.c @@ -17,7 +17,7 @@ #include "midx.h" #include "packfile.h" #include "prune-packed.h" -#include "object-store.h" +#include "odb.h" #include "promisor-remote.h" #include "shallow.h" #include "pack.h" diff --git a/builtin/replace.c b/builtin/replace.c index 48c7c6a2d5..11c7e2d4c0 100644 --- a/builtin/replace.c +++ b/builtin/replace.c @@ -19,7 +19,7 @@ #include "run-command.h" #include "object-file.h" #include "object-name.h" -#include "object-store.h" +#include "odb.h" #include "replace-object.h" #include "tag.h" #include "wildmatch.h" diff --git a/builtin/rev-list.c b/builtin/rev-list.c index 0984b607bf..0ee37a32cb 100644 --- a/builtin/rev-list.c +++ b/builtin/rev-list.c @@ -14,7 +14,7 @@ #include "object.h" #include "object-name.h" #include "object-file.h" -#include "object-store.h" +#include "odb.h" #include "pack-bitmap.h" #include "parse-options.h" #include "log-tree.h" diff --git a/builtin/show-ref.c b/builtin/show-ref.c index 623a52a45f..90ec1de78f 100644 --- a/builtin/show-ref.c +++ b/builtin/show-ref.c @@ -5,7 +5,7 @@ #include "hex.h" #include "refs/refs-internal.h" #include "object-name.h" -#include "object-store.h" +#include "odb.h" #include "object.h" #include "string-list.h" #include "parse-options.h" diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 758bc6d0f2..84f7fa5342 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -28,7 +28,7 @@ #include "diff.h" #include "object-file.h" #include "object-name.h" -#include "object-store.h" +#include "odb.h" #include "advice.h" #include "branch.h" #include "list-objects-filter-options.h" diff --git a/builtin/tag.c b/builtin/tag.c index 4742b27d16..cf2ea4b499 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -19,7 +19,7 @@ #include "refs.h" #include "object-file.h" #include "object-name.h" -#include "object-store.h" +#include "odb.h" #include "path.h" #include "tag.h" #include "parse-options.h" diff --git a/builtin/unpack-file.c b/builtin/unpack-file.c index e33acfc4ee..b92fd4710a 100644 --- a/builtin/unpack-file.c +++ b/builtin/unpack-file.c @@ -4,7 +4,7 @@ #include "hex.h" #include "object-file.h" #include "object-name.h" -#include "object-store.h" +#include "odb.h" static char *create_temp_file(struct object_id *oid) { diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c index e905d5f4e1..7bf395eec8 100644 --- a/builtin/unpack-objects.c +++ b/builtin/unpack-objects.c @@ -9,7 +9,7 @@ #include "git-zlib.h" #include "hex.h" #include "object-file.h" -#include "object-store.h" +#include "odb.h" #include "object.h" #include "delta.h" #include "pack.h" diff --git a/bulk-checkin.c b/bulk-checkin.c index 678e2ecc2c..55406a539e 100644 --- a/bulk-checkin.c +++ b/bulk-checkin.c @@ -17,7 +17,7 @@ #include "tmp-objdir.h" #include "packfile.h" #include "object-file.h" -#include "object-store.h" +#include "odb.h" static int odb_transaction_nesting; diff --git a/bundle-uri.c b/bundle-uri.c index 9accf157b4..2e623f8627 100644 --- a/bundle-uri.c +++ b/bundle-uri.c @@ -14,7 +14,7 @@ #include "fetch-pack.h" #include "remote.h" #include "trace2.h" -#include "object-store.h" +#include "odb.h" static struct { enum bundle_list_heuristic heuristic; diff --git a/bundle.c b/bundle.c index 2ce7525f90..e09e3c2f58 100644 --- a/bundle.c +++ b/bundle.c @@ -7,7 +7,7 @@ #include "environment.h" #include "gettext.h" #include "hex.h" -#include "object-store.h" +#include "odb.h" #include "repository.h" #include "object.h" #include "commit.h" diff --git a/cache-tree.c b/cache-tree.c index fa3858e282..9786b32b3a 100644 --- a/cache-tree.c +++ b/cache-tree.c @@ -10,7 +10,7 @@ #include "cache-tree.h" #include "bulk-checkin.h" #include "object-file.h" -#include "object-store.h" +#include "odb.h" #include "read-cache-ll.h" #include "replace-object.h" #include "repository.h" diff --git a/combine-diff.c b/combine-diff.c index dfae9f7995..cf23a75340 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -2,7 +2,7 @@ #define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" -#include "object-store.h" +#include "odb.h" #include "commit.h" #include "convert.h" #include "diff.h" diff --git a/commit-graph.c b/commit-graph.c index 12d32cdad1..6ced5b366e 100644 --- a/commit-graph.c +++ b/commit-graph.c @@ -13,7 +13,7 @@ #include "refs.h" #include "hash-lookup.h" #include "commit-graph.h" -#include "object-store.h" +#include "odb.h" #include "oid-array.h" #include "path.h" #include "alloc.h" diff --git a/commit-graph.h b/commit-graph.h index 0e661db1b5..78ab7b875b 100644 --- a/commit-graph.h +++ b/commit-graph.h @@ -1,7 +1,7 @@ #ifndef COMMIT_GRAPH_H #define COMMIT_GRAPH_H -#include "object-store.h" +#include "odb.h" #include "oidset.h" #define GIT_TEST_COMMIT_GRAPH "GIT_TEST_COMMIT_GRAPH" diff --git a/commit.c b/commit.c index e915b2b9a1..1d30f8ce15 100644 --- a/commit.c +++ b/commit.c @@ -9,7 +9,7 @@ #include "hex.h" #include "repository.h" #include "object-name.h" -#include "object-store.h" +#include "odb.h" #include "utf8.h" #include "diff.h" #include "revision.h" diff --git a/config.c b/config.c index b18b5617fc..883dd06682 100644 --- a/config.c +++ b/config.c @@ -31,7 +31,7 @@ #include "hashmap.h" #include "string-list.h" #include "object-name.h" -#include "object-store.h" +#include "odb.h" #include "pager.h" #include "path.h" #include "utf8.h" diff --git a/connected.c b/connected.c index 4415388beb..18c13245d8 100644 --- a/connected.c +++ b/connected.c @@ -3,7 +3,7 @@ #include "git-compat-util.h" #include "gettext.h" #include "hex.h" -#include "object-store.h" +#include "odb.h" #include "run-command.h" #include "sigchain.h" #include "connected.h" diff --git a/contrib/coccinelle/the_repository.cocci b/contrib/coccinelle/the_repository.cocci index 765ad68967..ea7fe1c8db 100644 --- a/contrib/coccinelle/the_repository.cocci +++ b/contrib/coccinelle/the_repository.cocci @@ -77,7 +77,7 @@ | - diff_setup + repo_diff_setup -// object-store.h +// odb.h | - read_object_file + repo_read_object_file diff --git a/diagnose.c b/diagnose.c index d08d5643aa..ad0d5c1246 100644 --- a/diagnose.c +++ b/diagnose.c @@ -7,7 +7,7 @@ #include "gettext.h" #include "hex.h" #include "strvec.h" -#include "object-store.h" +#include "odb.h" #include "packfile.h" #include "parse-options.h" #include "repository.h" diff --git a/diff.c b/diff.c index 90e8003dd1..3af108115b 100644 --- a/diff.c +++ b/diff.c @@ -23,7 +23,7 @@ #include "color.h" #include "run-command.h" #include "utf8.h" -#include "object-store.h" +#include "odb.h" #include "userdiff.h" #include "submodule.h" #include "hashmap.h" diff --git a/entry.c b/entry.c index f36ec5ad24..75d55038d7 100644 --- a/entry.c +++ b/entry.c @@ -1,7 +1,7 @@ #define USE_THE_REPOSITORY_VARIABLE #include "git-compat-util.h" -#include "object-store.h" +#include "odb.h" #include "dir.h" #include "environment.h" #include "gettext.h" diff --git a/fetch-pack.c b/fetch-pack.c index fa4231fee7..cf157f5d7e 100644 --- a/fetch-pack.c +++ b/fetch-pack.c @@ -24,7 +24,7 @@ #include "oid-array.h" #include "oidset.h" #include "packfile.h" -#include "object-store.h" +#include "odb.h" #include "path.h" #include "connected.h" #include "fetch-negotiator.h" diff --git a/fmt-merge-msg.c b/fmt-merge-msg.c index 501b5acdd4..1a8c972adf 100644 --- a/fmt-merge-msg.c +++ b/fmt-merge-msg.c @@ -6,7 +6,7 @@ #include "environment.h" #include "refs.h" #include "object-name.h" -#include "object-store.h" +#include "odb.h" #include "diff.h" #include "diff-merges.h" #include "hex.h" diff --git a/fsck.c b/fsck.c index 8dc8472ceb..e69baab3af 100644 --- a/fsck.c +++ b/fsck.c @@ -4,7 +4,7 @@ #include "date.h" #include "dir.h" #include "hex.h" -#include "object-store.h" +#include "odb.h" #include "path.h" #include "repository.h" #include "object.h" diff --git a/grep.c b/grep.c index f8d535182c..dc77e6c463 100644 --- a/grep.c +++ b/grep.c @@ -5,7 +5,7 @@ #include "gettext.h" #include "grep.h" #include "hex.h" -#include "object-store.h" +#include "odb.h" #include "pretty.h" #include "userdiff.h" #include "xdiff-interface.h" diff --git a/http-backend.c b/http-backend.c index 0c575aa88a..ad8c403749 100644 --- a/http-backend.c +++ b/http-backend.c @@ -18,7 +18,7 @@ #include "url.h" #include "strvec.h" #include "packfile.h" -#include "object-store.h" +#include "odb.h" #include "protocol.h" #include "date.h" #include "write-or-die.h" diff --git a/http-push.c b/http-push.c index f9e67cabd4..d1b1bb2371 100644 --- a/http-push.c +++ b/http-push.c @@ -20,7 +20,7 @@ #include "url.h" #include "packfile.h" #include "object-file.h" -#include "object-store.h" +#include "odb.h" #include "commit-reach.h" #ifdef EXPAT_NEEDS_XMLPARSE_H diff --git a/http-walker.c b/http-walker.c index c374e6b205..05fb9ce714 100644 --- a/http-walker.c +++ b/http-walker.c @@ -10,7 +10,7 @@ #include "transport.h" #include "packfile.h" #include "object-file.h" -#include "object-store.h" +#include "odb.h" struct alt_base { char *base; diff --git a/http.c b/http.c index 5e15bbab3f..8f4f701a81 100644 --- a/http.c +++ b/http.c @@ -19,7 +19,7 @@ #include "packfile.h" #include "string-list.h" #include "object-file.h" -#include "object-store.h" +#include "odb.h" #include "tempfile.h" static struct trace_key trace_curl = TRACE_KEY_INIT(CURL); diff --git a/list-objects-filter.c b/list-objects-filter.c index 78b397bc19..80fe48a52c 100644 --- a/list-objects-filter.c +++ b/list-objects-filter.c @@ -12,7 +12,7 @@ #include "oidmap.h" #include "oidset.h" #include "object-name.h" -#include "object-store.h" +#include "odb.h" /* Remember to update object flag allocation in object.h */ /* diff --git a/list-objects.c b/list-objects.c index 597114281f..c50b957858 100644 --- a/list-objects.c +++ b/list-objects.c @@ -14,7 +14,7 @@ #include "list-objects-filter.h" #include "list-objects-filter-options.h" #include "packfile.h" -#include "object-store.h" +#include "odb.h" #include "trace.h" #include "environment.h" diff --git a/loose.c b/loose.c index fe65d5b9b0..fab4041c03 100644 --- a/loose.c +++ b/loose.c @@ -1,7 +1,7 @@ #include "git-compat-util.h" #include "hash.h" #include "path.h" -#include "object-store.h" +#include "odb.h" #include "hex.h" #include "repository.h" #include "wrapper.h" diff --git a/mailmap.c b/mailmap.c index 9e2642a043..b18e74c211 100644 --- a/mailmap.c +++ b/mailmap.c @@ -6,7 +6,7 @@ #include "string-list.h" #include "mailmap.h" #include "object-name.h" -#include "object-store.h" +#include "odb.h" #include "setup.h" char *git_mailmap_file; diff --git a/match-trees.c b/match-trees.c index 72922d5d64..4704f95c34 100644 --- a/match-trees.c +++ b/match-trees.c @@ -7,7 +7,7 @@ #include "tree.h" #include "tree-walk.h" #include "object-file.h" -#include "object-store.h" +#include "odb.h" #include "repository.h" static int score_missing(unsigned mode) diff --git a/merge-blobs.c b/merge-blobs.c index 53f36dbc17..ba8a3fdfd8 100644 --- a/merge-blobs.c +++ b/merge-blobs.c @@ -4,7 +4,7 @@ #include "merge-ll.h" #include "blob.h" #include "merge-blobs.h" -#include "object-store.h" +#include "odb.h" static int fill_mmfile_blob(mmfile_t *f, struct blob *obj) { diff --git a/merge-ort.c b/merge-ort.c index 47b3d1730e..9f693ab1d3 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -39,7 +39,7 @@ #include "mem-pool.h" #include "object-file.h" #include "object-name.h" -#include "object-store.h" +#include "odb.h" #include "oid-array.h" #include "path.h" #include "promisor-remote.h" diff --git a/meson.build b/meson.build index 596f5ac711..3fad0e3998 100644 --- a/meson.build +++ b/meson.build @@ -396,8 +396,8 @@ libgit_sources = [ 'object-file-convert.c', 'object-file.c', 'object-name.c', - 'object-store.c', 'object.c', + 'odb.c', 'oid-array.c', 'oidmap.c', 'oidset.c', diff --git a/notes-cache.c b/notes-cache.c index 150241b15e..344f67762b 100644 --- a/notes-cache.c +++ b/notes-cache.c @@ -3,7 +3,7 @@ #include "git-compat-util.h" #include "notes-cache.h" #include "object-file.h" -#include "object-store.h" +#include "odb.h" #include "pretty.h" #include "repository.h" #include "commit.h" diff --git a/notes-merge.c b/notes-merge.c index dae8e6a281..de6a52e2e7 100644 --- a/notes-merge.c +++ b/notes-merge.c @@ -8,7 +8,7 @@ #include "refs.h" #include "object-file.h" #include "object-name.h" -#include "object-store.h" +#include "odb.h" #include "path.h" #include "repository.h" #include "diff.h" diff --git a/notes.c b/notes.c index 0a128f1de9..fc000e501d 100644 --- a/notes.c +++ b/notes.c @@ -8,7 +8,7 @@ #include "notes.h" #include "object-file.h" #include "object-name.h" -#include "object-store.h" +#include "odb.h" #include "utf8.h" #include "strbuf.h" #include "tree-walk.h" diff --git a/object-file.c b/object-file.c index 6bad1d3dd1..2d3af8a77c 100644 --- a/object-file.c +++ b/object-file.c @@ -21,7 +21,7 @@ #include "loose.h" #include "object-file-convert.h" #include "object-file.h" -#include "object-store.h" +#include "odb.h" #include "oidtree.h" #include "pack.h" #include "packfile.h" diff --git a/object-file.h b/object-file.h index 9a18859b2e..5066638f8e 100644 --- a/object-file.h +++ b/object-file.h @@ -3,7 +3,7 @@ #include "git-zlib.h" #include "object.h" -#include "object-store.h" +#include "odb.h" struct index_state; diff --git a/object-store.c b/object-store.c deleted file mode 100644 index 5c04a1018f..0000000000 --- a/object-store.c +++ /dev/null @@ -1,1010 +0,0 @@ -#define USE_THE_REPOSITORY_VARIABLE - -#include "git-compat-util.h" -#include "abspath.h" -#include "commit-graph.h" -#include "config.h" -#include "dir.h" -#include "environment.h" -#include "gettext.h" -#include "hex.h" -#include "khash.h" -#include "lockfile.h" -#include "loose.h" -#include "object-file-convert.h" -#include "object-file.h" -#include "object-store.h" -#include "packfile.h" -#include "path.h" -#include "promisor-remote.h" -#include "quote.h" -#include "replace-object.h" -#include "run-command.h" -#include "setup.h" -#include "strbuf.h" -#include "strvec.h" -#include "submodule.h" -#include "write-or-die.h" - -KHASH_INIT(odb_path_map, const char * /* key: odb_path */, - struct odb_source *, 1, fspathhash, fspatheq) - -/* - * This is meant to hold a *small* number of objects that you would - * want repo_read_object_file() to be able to return, but yet you do not want - * to write them into the object store (e.g. a browse-only - * application). - */ -struct cached_object_entry { - struct object_id oid; - struct cached_object { - enum object_type type; - const void *buf; - unsigned long size; - } value; -}; - -static const struct cached_object *find_cached_object(struct object_database *object_store, - const struct object_id *oid) -{ - static const struct cached_object empty_tree = { - .type = OBJ_TREE, - .buf = "", - }; - const struct cached_object_entry *co = object_store->cached_objects; - - for (size_t i = 0; i < object_store->cached_object_nr; i++, co++) - if (oideq(&co->oid, oid)) - return &co->value; - - if (oid->algo && oideq(oid, hash_algos[oid->algo].empty_tree)) - return &empty_tree; - - return NULL; -} - -int odb_mkstemp(struct strbuf *temp_filename, const char *pattern) -{ - int fd; - /* - * we let the umask do its job, don't try to be more - * restrictive except to remove write permission. - */ - int mode = 0444; - repo_git_path_replace(the_repository, temp_filename, "objects/%s", pattern); - fd = git_mkstemp_mode(temp_filename->buf, mode); - if (0 <= fd) - return fd; - - /* slow path */ - /* some mkstemp implementations erase temp_filename on failure */ - repo_git_path_replace(the_repository, temp_filename, "objects/%s", pattern); - safe_create_leading_directories(the_repository, temp_filename->buf); - return xmkstemp_mode(temp_filename->buf, mode); -} - -/* - * Return non-zero iff the path is usable as an alternate object database. - */ -static int alt_odb_usable(struct object_database *o, - struct strbuf *path, - const char *normalized_objdir, khiter_t *pos) -{ - int r; - - /* Detect cases where alternate disappeared */ - if (!is_directory(path->buf)) { - error(_("object directory %s does not exist; " - "check .git/objects/info/alternates"), - path->buf); - return 0; - } - - /* - * Prevent the common mistake of listing the same - * thing twice, or object directory itself. - */ - if (!o->source_by_path) { - khiter_t p; - - o->source_by_path = kh_init_odb_path_map(); - assert(!o->sources->next); - p = kh_put_odb_path_map(o->source_by_path, o->sources->path, &r); - assert(r == 1); /* never used */ - kh_value(o->source_by_path, p) = o->sources; - } - if (fspatheq(path->buf, normalized_objdir)) - return 0; - *pos = kh_put_odb_path_map(o->source_by_path, path->buf, &r); - /* r: 0 = exists, 1 = never used, 2 = deleted */ - return r == 0 ? 0 : 1; -} - -/* - * Prepare alternate object database registry. - * - * The variable alt_odb_list points at the list of struct - * odb_source. The elements on this list come from - * non-empty elements from colon separated ALTERNATE_DB_ENVIRONMENT - * environment variable, and $GIT_OBJECT_DIRECTORY/info/alternates, - * whose contents is similar to that environment variable but can be - * LF separated. Its base points at a statically allocated buffer that - * contains "/the/directory/corresponding/to/.git/objects/...", while - * its name points just after the slash at the end of ".git/objects/" - * in the example above, and has enough space to hold all hex characters - * of the object ID, an extra slash for the first level indirection, and - * the terminating NUL. - */ -static void read_info_alternates(struct repository *r, - const char *relative_base, - int depth); -static int link_alt_odb_entry(struct repository *r, const struct strbuf *entry, - const char *relative_base, int depth, const char *normalized_objdir) -{ - struct odb_source *alternate; - struct strbuf pathbuf = STRBUF_INIT; - struct strbuf tmp = STRBUF_INIT; - khiter_t pos; - int ret = -1; - - if (!is_absolute_path(entry->buf) && relative_base) { - strbuf_realpath(&pathbuf, relative_base, 1); - strbuf_addch(&pathbuf, '/'); - } - strbuf_addbuf(&pathbuf, entry); - - if (!strbuf_realpath(&tmp, pathbuf.buf, 0)) { - error(_("unable to normalize alternate object path: %s"), - pathbuf.buf); - goto error; - } - strbuf_swap(&pathbuf, &tmp); - - /* - * The trailing slash after the directory name is given by - * this function at the end. Remove duplicates. - */ - while (pathbuf.len && pathbuf.buf[pathbuf.len - 1] == '/') - strbuf_setlen(&pathbuf, pathbuf.len - 1); - - if (!alt_odb_usable(r->objects, &pathbuf, normalized_objdir, &pos)) - goto error; - - CALLOC_ARRAY(alternate, 1); - /* pathbuf.buf is already in r->objects->source_by_path */ - alternate->path = strbuf_detach(&pathbuf, NULL); - - /* add the alternate entry */ - *r->objects->sources_tail = alternate; - r->objects->sources_tail = &(alternate->next); - alternate->next = NULL; - assert(r->objects->source_by_path); - kh_value(r->objects->source_by_path, pos) = alternate; - - /* recursively add alternates */ - read_info_alternates(r, alternate->path, depth + 1); - ret = 0; - error: - strbuf_release(&tmp); - strbuf_release(&pathbuf); - return ret; -} - -static const char *parse_alt_odb_entry(const char *string, - int sep, - struct strbuf *out) -{ - const char *end; - - strbuf_reset(out); - - if (*string == '#') { - /* comment; consume up to next separator */ - end = strchrnul(string, sep); - } else if (*string == '"' && !unquote_c_style(out, string, &end)) { - /* - * quoted path; unquote_c_style has copied the - * data for us and set "end". Broken quoting (e.g., - * an entry that doesn't end with a quote) falls - * back to the unquoted case below. - */ - } else { - /* normal, unquoted path */ - end = strchrnul(string, sep); - strbuf_add(out, string, end - string); - } - - if (*end) - end++; - return end; -} - -static void link_alt_odb_entries(struct repository *r, const char *alt, - int sep, const char *relative_base, int depth) -{ - struct strbuf objdirbuf = STRBUF_INIT; - struct strbuf entry = STRBUF_INIT; - - if (!alt || !*alt) - return; - - if (depth > 5) { - error(_("%s: ignoring alternate object stores, nesting too deep"), - relative_base); - return; - } - - strbuf_realpath(&objdirbuf, r->objects->sources->path, 1); - - while (*alt) { - alt = parse_alt_odb_entry(alt, sep, &entry); - if (!entry.len) - continue; - link_alt_odb_entry(r, &entry, - relative_base, depth, objdirbuf.buf); - } - strbuf_release(&entry); - strbuf_release(&objdirbuf); -} - -static void read_info_alternates(struct repository *r, - const char *relative_base, - int depth) -{ - char *path; - struct strbuf buf = STRBUF_INIT; - - path = xstrfmt("%s/info/alternates", relative_base); - if (strbuf_read_file(&buf, path, 1024) < 0) { - warn_on_fopen_errors(path); - free(path); - return; - } - - link_alt_odb_entries(r, buf.buf, '\n', relative_base, depth); - strbuf_release(&buf); - free(path); -} - -void add_to_alternates_file(const char *reference) -{ - struct lock_file lock = LOCK_INIT; - char *alts = repo_git_path(the_repository, "objects/info/alternates"); - FILE *in, *out; - int found = 0; - - hold_lock_file_for_update(&lock, alts, LOCK_DIE_ON_ERROR); - out = fdopen_lock_file(&lock, "w"); - if (!out) - die_errno(_("unable to fdopen alternates lockfile")); - - in = fopen(alts, "r"); - if (in) { - struct strbuf line = STRBUF_INIT; - - while (strbuf_getline(&line, in) != EOF) { - if (!strcmp(reference, line.buf)) { - found = 1; - break; - } - fprintf_or_die(out, "%s\n", line.buf); - } - - strbuf_release(&line); - fclose(in); - } - else if (errno != ENOENT) - die_errno(_("unable to read alternates file")); - - if (found) { - rollback_lock_file(&lock); - } else { - fprintf_or_die(out, "%s\n", reference); - if (commit_lock_file(&lock)) - die_errno(_("unable to move new alternates file into place")); - if (the_repository->objects->loaded_alternates) - link_alt_odb_entries(the_repository, reference, - '\n', NULL, 0); - } - free(alts); -} - -void add_to_alternates_memory(const char *reference) -{ - /* - * Make sure alternates are initialized, or else our entry may be - * overwritten when they are. - */ - prepare_alt_odb(the_repository); - - link_alt_odb_entries(the_repository, reference, - '\n', NULL, 0); -} - -struct odb_source *set_temporary_primary_odb(const char *dir, int will_destroy) -{ - struct odb_source *source; - - /* - * Make sure alternates are initialized, or else our entry may be - * overwritten when they are. - */ - prepare_alt_odb(the_repository); - - /* - * Make a new primary odb and link the old primary ODB in as an - * alternate - */ - source = xcalloc(1, sizeof(*source)); - source->path = xstrdup(dir); - - /* - * Disable ref updates while a temporary odb is active, since - * the objects in the database may roll back. - */ - source->disable_ref_updates = 1; - source->will_destroy = will_destroy; - source->next = the_repository->objects->sources; - the_repository->objects->sources = source; - return source->next; -} - -static void free_object_directory(struct odb_source *source) -{ - free(source->path); - odb_clear_loose_cache(source); - loose_object_map_clear(&source->loose_map); - free(source); -} - -void restore_primary_odb(struct odb_source *restore_alt, const char *old_path) -{ - struct odb_source *cur_alt = the_repository->objects->sources; - - if (strcmp(old_path, cur_alt->path)) - BUG("expected %s as primary object store; found %s", - old_path, cur_alt->path); - - if (cur_alt->next != restore_alt) - BUG("we expect the old primary object store to be the first alternate"); - - the_repository->objects->sources = restore_alt; - free_object_directory(cur_alt); -} - -/* - * Compute the exact path an alternate is at and returns it. In case of - * error NULL is returned and the human readable error is added to `err` - * `path` may be relative and should point to $GIT_DIR. - * `err` must not be null. - */ -char *compute_alternate_path(const char *path, struct strbuf *err) -{ - char *ref_git = NULL; - const char *repo; - int seen_error = 0; - - ref_git = real_pathdup(path, 0); - if (!ref_git) { - seen_error = 1; - strbuf_addf(err, _("path '%s' does not exist"), path); - goto out; - } - - repo = read_gitfile(ref_git); - if (!repo) - repo = read_gitfile(mkpath("%s/.git", ref_git)); - if (repo) { - free(ref_git); - ref_git = xstrdup(repo); - } - - if (!repo && is_directory(mkpath("%s/.git/objects", ref_git))) { - char *ref_git_git = mkpathdup("%s/.git", ref_git); - free(ref_git); - ref_git = ref_git_git; - } else if (!is_directory(mkpath("%s/objects", ref_git))) { - struct strbuf sb = STRBUF_INIT; - seen_error = 1; - if (get_common_dir(&sb, ref_git)) { - strbuf_addf(err, - _("reference repository '%s' as a linked " - "checkout is not supported yet."), - path); - goto out; - } - - strbuf_addf(err, _("reference repository '%s' is not a " - "local repository."), path); - goto out; - } - - if (!access(mkpath("%s/shallow", ref_git), F_OK)) { - strbuf_addf(err, _("reference repository '%s' is shallow"), - path); - seen_error = 1; - goto out; - } - - if (!access(mkpath("%s/info/grafts", ref_git), F_OK)) { - strbuf_addf(err, - _("reference repository '%s' is grafted"), - path); - seen_error = 1; - goto out; - } - -out: - if (seen_error) { - FREE_AND_NULL(ref_git); - } - - return ref_git; -} - -struct odb_source *find_odb(struct repository *r, const char *obj_dir) -{ - struct odb_source *source; - char *obj_dir_real = real_pathdup(obj_dir, 1); - struct strbuf odb_path_real = STRBUF_INIT; - - prepare_alt_odb(r); - for (source = r->objects->sources; source; source = source->next) { - strbuf_realpath(&odb_path_real, source->path, 1); - if (!strcmp(obj_dir_real, odb_path_real.buf)) - break; - } - - free(obj_dir_real); - strbuf_release(&odb_path_real); - - if (!source) - die(_("could not find object directory matching %s"), obj_dir); - return source; -} - -static void fill_alternate_refs_command(struct child_process *cmd, - const char *repo_path) -{ - const char *value; - - if (!git_config_get_value("core.alternateRefsCommand", &value)) { - cmd->use_shell = 1; - - strvec_push(&cmd->args, value); - strvec_push(&cmd->args, repo_path); - } else { - cmd->git_cmd = 1; - - strvec_pushf(&cmd->args, "--git-dir=%s", repo_path); - strvec_push(&cmd->args, "for-each-ref"); - strvec_push(&cmd->args, "--format=%(objectname)"); - - if (!git_config_get_value("core.alternateRefsPrefixes", &value)) { - strvec_push(&cmd->args, "--"); - strvec_split(&cmd->args, value); - } - } - - strvec_pushv(&cmd->env, (const char **)local_repo_env); - cmd->out = -1; -} - -static void read_alternate_refs(const char *path, - alternate_ref_fn *cb, - void *data) -{ - struct child_process cmd = CHILD_PROCESS_INIT; - struct strbuf line = STRBUF_INIT; - FILE *fh; - - fill_alternate_refs_command(&cmd, path); - - if (start_command(&cmd)) - return; - - fh = xfdopen(cmd.out, "r"); - while (strbuf_getline_lf(&line, fh) != EOF) { - struct object_id oid; - const char *p; - - if (parse_oid_hex(line.buf, &oid, &p) || *p) { - warning(_("invalid line while parsing alternate refs: %s"), - line.buf); - break; - } - - cb(&oid, data); - } - - fclose(fh); - finish_command(&cmd); - strbuf_release(&line); -} - -struct alternate_refs_data { - alternate_ref_fn *fn; - void *data; -}; - -static int refs_from_alternate_cb(struct odb_source *alternate, - void *data) -{ - struct strbuf path = STRBUF_INIT; - size_t base_len; - struct alternate_refs_data *cb = data; - - if (!strbuf_realpath(&path, alternate->path, 0)) - goto out; - if (!strbuf_strip_suffix(&path, "/objects")) - goto out; - base_len = path.len; - - /* Is this a git repository with refs? */ - strbuf_addstr(&path, "/refs"); - if (!is_directory(path.buf)) - goto out; - strbuf_setlen(&path, base_len); - - read_alternate_refs(path.buf, cb->fn, cb->data); - -out: - strbuf_release(&path); - return 0; -} - -void for_each_alternate_ref(alternate_ref_fn fn, void *data) -{ - struct alternate_refs_data cb; - cb.fn = fn; - cb.data = data; - foreach_alt_odb(refs_from_alternate_cb, &cb); -} - -int foreach_alt_odb(alt_odb_fn fn, void *cb) -{ - struct odb_source *alternate; - int r = 0; - - prepare_alt_odb(the_repository); - for (alternate = the_repository->objects->sources->next; alternate; alternate = alternate->next) { - r = fn(alternate, cb); - if (r) - break; - } - return r; -} - -void prepare_alt_odb(struct repository *r) -{ - if (r->objects->loaded_alternates) - return; - - link_alt_odb_entries(r, r->objects->alternate_db, PATH_SEP, NULL, 0); - - read_info_alternates(r, r->objects->sources->path, 0); - r->objects->loaded_alternates = 1; -} - -int has_alt_odb(struct repository *r) -{ - prepare_alt_odb(r); - return !!r->objects->sources->next; -} - -int obj_read_use_lock = 0; -pthread_mutex_t obj_read_mutex; - -void enable_obj_read_lock(void) -{ - if (obj_read_use_lock) - return; - - obj_read_use_lock = 1; - init_recursive_mutex(&obj_read_mutex); -} - -void disable_obj_read_lock(void) -{ - if (!obj_read_use_lock) - return; - - obj_read_use_lock = 0; - pthread_mutex_destroy(&obj_read_mutex); -} - -int fetch_if_missing = 1; - -static int do_oid_object_info_extended(struct repository *r, - const struct object_id *oid, - struct object_info *oi, unsigned flags) -{ - static struct object_info blank_oi = OBJECT_INFO_INIT; - const struct cached_object *co; - struct pack_entry e; - int rtype; - const struct object_id *real = oid; - int already_retried = 0; - - - if (flags & OBJECT_INFO_LOOKUP_REPLACE) - real = lookup_replace_object(r, oid); - - if (is_null_oid(real)) - return -1; - - if (!oi) - oi = &blank_oi; - - co = find_cached_object(r->objects, real); - if (co) { - if (oi->typep) - *(oi->typep) = co->type; - if (oi->sizep) - *(oi->sizep) = co->size; - if (oi->disk_sizep) - *(oi->disk_sizep) = 0; - if (oi->delta_base_oid) - oidclr(oi->delta_base_oid, the_repository->hash_algo); - if (oi->contentp) - *oi->contentp = xmemdupz(co->buf, co->size); - oi->whence = OI_CACHED; - return 0; - } - - while (1) { - if (find_pack_entry(r, real, &e)) - break; - - /* Most likely it's a loose object. */ - if (!loose_object_info(r, real, oi, flags)) - return 0; - - /* Not a loose object; someone else may have just packed it. */ - if (!(flags & OBJECT_INFO_QUICK)) { - reprepare_packed_git(r); - if (find_pack_entry(r, real, &e)) - break; - } - - /* - * If r is the_repository, this might be an attempt at - * accessing a submodule object as if it were in the_repository - * (having called add_submodule_odb() on that submodule's ODB). - * If any such ODBs exist, register them and try again. - */ - if (r == the_repository && - register_all_submodule_odb_as_alternates()) - /* We added some alternates; retry */ - continue; - - /* Check if it is a missing object */ - if (fetch_if_missing && repo_has_promisor_remote(r) && - !already_retried && - !(flags & OBJECT_INFO_SKIP_FETCH_OBJECT)) { - promisor_remote_get_direct(r, real, 1); - already_retried = 1; - continue; - } - - if (flags & OBJECT_INFO_DIE_IF_CORRUPT) { - const struct packed_git *p; - if ((flags & OBJECT_INFO_LOOKUP_REPLACE) && !oideq(real, oid)) - die(_("replacement %s not found for %s"), - oid_to_hex(real), oid_to_hex(oid)); - if ((p = has_packed_and_bad(r, real))) - die(_("packed object %s (stored in %s) is corrupt"), - oid_to_hex(real), p->pack_name); - } - return -1; - } - - if (oi == &blank_oi) - /* - * We know that the caller doesn't actually need the - * information below, so return early. - */ - return 0; - rtype = packed_object_info(r, e.p, e.offset, oi); - if (rtype < 0) { - mark_bad_packed_object(e.p, real); - return do_oid_object_info_extended(r, real, oi, 0); - } else if (oi->whence == OI_PACKED) { - oi->u.packed.offset = e.offset; - oi->u.packed.pack = e.p; - oi->u.packed.is_delta = (rtype == OBJ_REF_DELTA || - rtype == OBJ_OFS_DELTA); - } - - return 0; -} - -static int oid_object_info_convert(struct repository *r, - const struct object_id *input_oid, - struct object_info *input_oi, unsigned flags) -{ - const struct git_hash_algo *input_algo = &hash_algos[input_oid->algo]; - int do_die = flags & OBJECT_INFO_DIE_IF_CORRUPT; - enum object_type type; - struct object_id oid, delta_base_oid; - struct object_info new_oi, *oi; - unsigned long size; - void *content; - int ret; - - if (repo_oid_to_algop(r, input_oid, the_hash_algo, &oid)) { - if (do_die) - die(_("missing mapping of %s to %s"), - oid_to_hex(input_oid), the_hash_algo->name); - return -1; - } - - /* Is new_oi needed? */ - oi = input_oi; - if (input_oi && (input_oi->delta_base_oid || input_oi->sizep || - input_oi->contentp)) { - new_oi = *input_oi; - /* Does delta_base_oid need to be converted? */ - if (input_oi->delta_base_oid) - new_oi.delta_base_oid = &delta_base_oid; - /* Will the attributes differ when converted? */ - if (input_oi->sizep || input_oi->contentp) { - new_oi.contentp = &content; - new_oi.sizep = &size; - new_oi.typep = &type; - } - oi = &new_oi; - } - - ret = oid_object_info_extended(r, &oid, oi, flags); - if (ret) - return -1; - if (oi == input_oi) - return ret; - - if (new_oi.contentp) { - struct strbuf outbuf = STRBUF_INIT; - - if (type != OBJ_BLOB) { - ret = convert_object_file(the_repository, &outbuf, - the_hash_algo, input_algo, - content, size, type, !do_die); - free(content); - if (ret == -1) - return -1; - size = outbuf.len; - content = strbuf_detach(&outbuf, NULL); - } - if (input_oi->sizep) - *input_oi->sizep = size; - if (input_oi->contentp) - *input_oi->contentp = content; - else - free(content); - if (input_oi->typep) - *input_oi->typep = type; - } - if (new_oi.delta_base_oid == &delta_base_oid) { - if (repo_oid_to_algop(r, &delta_base_oid, input_algo, - input_oi->delta_base_oid)) { - if (do_die) - die(_("missing mapping of %s to %s"), - oid_to_hex(&delta_base_oid), - input_algo->name); - return -1; - } - } - input_oi->whence = new_oi.whence; - input_oi->u = new_oi.u; - return ret; -} - -int oid_object_info_extended(struct repository *r, const struct object_id *oid, - struct object_info *oi, unsigned flags) -{ - int ret; - - if (oid->algo && (hash_algo_by_ptr(r->hash_algo) != oid->algo)) - return oid_object_info_convert(r, oid, oi, flags); - - obj_read_lock(); - ret = do_oid_object_info_extended(r, oid, oi, flags); - obj_read_unlock(); - return ret; -} - - -/* returns enum object_type or negative */ -int oid_object_info(struct repository *r, - const struct object_id *oid, - unsigned long *sizep) -{ - enum object_type type; - struct object_info oi = OBJECT_INFO_INIT; - - oi.typep = &type; - oi.sizep = sizep; - if (oid_object_info_extended(r, oid, &oi, - OBJECT_INFO_LOOKUP_REPLACE) < 0) - return -1; - return type; -} - -int pretend_object_file(struct repository *repo, - void *buf, unsigned long len, enum object_type type, - struct object_id *oid) -{ - struct cached_object_entry *co; - char *co_buf; - - hash_object_file(repo->hash_algo, buf, len, type, oid); - if (has_object(repo, oid, 0) || - find_cached_object(repo->objects, oid)) - return 0; - - ALLOC_GROW(repo->objects->cached_objects, - repo->objects->cached_object_nr + 1, repo->objects->cached_object_alloc); - co = &repo->objects->cached_objects[repo->objects->cached_object_nr++]; - co->value.size = len; - co->value.type = type; - co_buf = xmalloc(len); - memcpy(co_buf, buf, len); - co->value.buf = co_buf; - oidcpy(&co->oid, oid); - return 0; -} - -/* - * This function dies on corrupt objects; the callers who want to - * deal with them should arrange to call oid_object_info_extended() and give - * error messages themselves. - */ -void *repo_read_object_file(struct repository *r, - const struct object_id *oid, - enum object_type *type, - unsigned long *size) -{ - struct object_info oi = OBJECT_INFO_INIT; - unsigned flags = OBJECT_INFO_DIE_IF_CORRUPT | OBJECT_INFO_LOOKUP_REPLACE; - void *data; - - oi.typep = type; - oi.sizep = size; - oi.contentp = &data; - if (oid_object_info_extended(r, oid, &oi, flags)) - return NULL; - - return data; -} - -void *read_object_with_reference(struct repository *r, - const struct object_id *oid, - enum object_type required_type, - unsigned long *size, - struct object_id *actual_oid_return) -{ - enum object_type type; - void *buffer; - unsigned long isize; - struct object_id actual_oid; - - oidcpy(&actual_oid, oid); - while (1) { - int ref_length = -1; - const char *ref_type = NULL; - - buffer = repo_read_object_file(r, &actual_oid, &type, &isize); - if (!buffer) - return NULL; - if (type == required_type) { - *size = isize; - if (actual_oid_return) - oidcpy(actual_oid_return, &actual_oid); - return buffer; - } - /* Handle references */ - else if (type == OBJ_COMMIT) - ref_type = "tree "; - else if (type == OBJ_TAG) - ref_type = "object "; - else { - free(buffer); - return NULL; - } - ref_length = strlen(ref_type); - - if (ref_length + the_hash_algo->hexsz > isize || - memcmp(buffer, ref_type, ref_length) || - get_oid_hex((char *) buffer + ref_length, &actual_oid)) { - free(buffer); - return NULL; - } - free(buffer); - /* Now we have the ID of the referred-to object in - * actual_oid. Check again. */ - } -} - -int has_object(struct repository *r, const struct object_id *oid, - unsigned flags) -{ - unsigned object_info_flags = 0; - - if (!startup_info->have_repository) - return 0; - if (!(flags & HAS_OBJECT_RECHECK_PACKED)) - object_info_flags |= OBJECT_INFO_QUICK; - if (!(flags & HAS_OBJECT_FETCH_PROMISOR)) - object_info_flags |= OBJECT_INFO_SKIP_FETCH_OBJECT; - - return oid_object_info_extended(r, oid, NULL, object_info_flags) >= 0; -} - -void assert_oid_type(const struct object_id *oid, enum object_type expect) -{ - enum object_type type = oid_object_info(the_repository, oid, NULL); - if (type < 0) - die(_("%s is not a valid object"), oid_to_hex(oid)); - if (type != expect) - die(_("%s is not a valid '%s' object"), oid_to_hex(oid), - type_name(expect)); -} - -struct object_database *odb_new(void) -{ - struct object_database *o = xmalloc(sizeof(*o)); - - memset(o, 0, sizeof(*o)); - INIT_LIST_HEAD(&o->packed_git_mru); - hashmap_init(&o->pack_map, pack_map_entry_cmp, NULL, 0); - pthread_mutex_init(&o->replace_mutex, NULL); - return o; -} - -static void free_object_directories(struct object_database *o) -{ - while (o->sources) { - struct odb_source *next; - - next = o->sources->next; - free_object_directory(o->sources); - o->sources = next; - } - kh_destroy_odb_path_map(o->source_by_path); - o->source_by_path = NULL; -} - -void odb_clear(struct object_database *o) -{ - FREE_AND_NULL(o->alternate_db); - - oidmap_clear(&o->replace_map, 1); - pthread_mutex_destroy(&o->replace_mutex); - - free_commit_graph(o->commit_graph); - o->commit_graph = NULL; - o->commit_graph_attempted = 0; - - free_object_directories(o); - o->sources_tail = NULL; - o->loaded_alternates = 0; - - for (size_t i = 0; i < o->cached_object_nr; i++) - free((char *) o->cached_objects[i].value.buf); - FREE_AND_NULL(o->cached_objects); - - INIT_LIST_HEAD(&o->packed_git_mru); - close_object_store(o); - - /* - * `close_object_store()` only closes the packfiles, but doesn't free - * them. We thus have to do this manually. - */ - for (struct packed_git *p = o->packed_git, *next; p; p = next) { - next = p->next; - free(p); - } - o->packed_git = NULL; - - hashmap_clear(&o->pack_map); -} diff --git a/object-store.h b/object-store.h deleted file mode 100644 index d199d757d7..0000000000 --- a/object-store.h +++ /dev/null @@ -1,355 +0,0 @@ -#ifndef OBJECT_STORE_H -#define OBJECT_STORE_H - -#include "hashmap.h" -#include "object.h" -#include "list.h" -#include "oidset.h" -#include "oidmap.h" -#include "thread-utils.h" - -struct oidmap; -struct oidtree; -struct strbuf; -struct repository; - -/* - * The source is the part of the object database that stores the actual - * objects. It thus encapsulates the logic to read and write the specific - * on-disk format. An object database can have multiple sources: - * - * - The primary source, which is typically located in "$GIT_DIR/objects". - * This is where new objects are usually written to. - * - * - Alternate sources, which are configured via "objects/info/alternates" or - * via the GIT_ALTERNATE_OBJECT_DIRECTORIES environment variable. These - * alternate sources are only used to read objects. - */ -struct odb_source { - struct odb_source *next; - - /* - * Used to store the results of readdir(3) calls when we are OK - * sacrificing accuracy due to races for speed. That includes - * object existence with OBJECT_INFO_QUICK, as well as - * our search for unique abbreviated hashes. Don't use it for tasks - * requiring greater accuracy! - * - * Be sure to call odb_load_loose_cache() before using. - */ - uint32_t loose_objects_subdir_seen[8]; /* 256 bits */ - struct oidtree *loose_objects_cache; - - /* Map between object IDs for loose objects. */ - struct loose_object_map *loose_map; - - /* - * This is a temporary object store created by the tmp_objdir - * facility. Disable ref updates since the objects in the store - * might be discarded on rollback. - */ - int disable_ref_updates; - - /* - * This object store is ephemeral, so there is no need to fsync. - */ - int will_destroy; - - /* - * Path to the source. If this is a relative path, it is relative to - * the current working directory. - */ - char *path; -}; - -void prepare_alt_odb(struct repository *r); -int has_alt_odb(struct repository *r); -char *compute_alternate_path(const char *path, struct strbuf *err); -struct odb_source *find_odb(struct repository *r, const char *obj_dir); -typedef int alt_odb_fn(struct odb_source *, void *); -int foreach_alt_odb(alt_odb_fn, void*); -typedef void alternate_ref_fn(const struct object_id *oid, void *); -void for_each_alternate_ref(alternate_ref_fn, void *); - -/* - * Add the directory to the on-disk alternates file; the new entry will also - * take effect in the current process. - */ -void add_to_alternates_file(const char *dir); - -/* - * Add the directory to the in-memory list of alternates (along with any - * recursive alternates it points to), but do not modify the on-disk alternates - * file. - */ -void add_to_alternates_memory(const char *dir); - -/* - * Replace the current writable object directory with the specified temporary - * object directory; returns the former primary object directory. - */ -struct odb_source *set_temporary_primary_odb(const char *dir, int will_destroy); - -/* - * Restore a previous ODB replaced by set_temporary_main_odb. - */ -void restore_primary_odb(struct odb_source *restore_alternate, const char *old_path); - -struct packed_git; -struct multi_pack_index; -struct cached_object_entry; - -/* - * The object database encapsulates access to objects in a repository. It - * manages one or more sources that store the actual objects which are - * configured via alternates. - */ -struct object_database { - /* - * Set of all object directories; the main directory is first (and - * cannot be NULL after initialization). Subsequent directories are - * alternates. - */ - struct odb_source *sources; - struct odb_source **sources_tail; - struct kh_odb_path_map *source_by_path; - - int loaded_alternates; - - /* - * A list of alternate object directories loaded from the environment; - * this should not generally need to be accessed directly, but will - * populate the "sources" list when prepare_alt_odb() is run. - */ - char *alternate_db; - - /* - * Objects that should be substituted by other objects - * (see git-replace(1)). - */ - struct oidmap replace_map; - unsigned replace_map_initialized : 1; - pthread_mutex_t replace_mutex; /* protect object replace functions */ - - struct commit_graph *commit_graph; - unsigned commit_graph_attempted : 1; /* if loading has been attempted */ - - /* - * private data - * - * should only be accessed directly by packfile.c and midx.c - */ - struct multi_pack_index *multi_pack_index; - - /* - * private data - * - * should only be accessed directly by packfile.c - */ - - struct packed_git *packed_git; - /* A most-recently-used ordered version of the packed_git list. */ - struct list_head packed_git_mru; - - struct { - struct packed_git **packs; - unsigned flags; - } kept_pack_cache; - - /* - * This is meant to hold a *small* number of objects that you would - * want repo_read_object_file() to be able to return, but yet you do not want - * to write them into the object store (e.g. a browse-only - * application). - */ - struct cached_object_entry *cached_objects; - size_t cached_object_nr, cached_object_alloc; - - /* - * A map of packfiles to packed_git structs for tracking which - * packs have been loaded already. - */ - struct hashmap pack_map; - - /* - * A fast, rough count of the number of objects in the repository. - * These two fields are not meant for direct access. Use - * repo_approximate_object_count() instead. - */ - unsigned long approximate_object_count; - unsigned approximate_object_count_valid : 1; - - /* - * Whether packed_git has already been populated with this repository's - * packs. - */ - unsigned packed_git_initialized : 1; -}; - -struct object_database *odb_new(void); -void odb_clear(struct object_database *o); - -/* - * Create a temporary file rooted in the object database directory, or - * die on failure. The filename is taken from "pattern", which should have the - * usual "XXXXXX" trailer, and the resulting filename is written into the - * "template" buffer. Returns the open descriptor. - */ -int odb_mkstemp(struct strbuf *temp_filename, const char *pattern); - -void *repo_read_object_file(struct repository *r, - const struct object_id *oid, - enum object_type *type, - unsigned long *size); - -/* Read and unpack an object file into memory, write memory to an object file */ -int oid_object_info(struct repository *r, const struct object_id *, unsigned long *); - -/* - * Add an object file to the in-memory object store, without writing it - * to disk. - * - * Callers are responsible for calling write_object_file to record the - * object in persistent storage before writing any other new objects - * that reference it. - */ -int pretend_object_file(struct repository *repo, - void *buf, unsigned long len, enum object_type type, - struct object_id *oid); - -struct object_info { - /* Request */ - enum object_type *typep; - unsigned long *sizep; - off_t *disk_sizep; - struct object_id *delta_base_oid; - void **contentp; - - /* Response */ - enum { - OI_CACHED, - OI_LOOSE, - OI_PACKED, - OI_DBCACHED - } whence; - union { - /* - * struct { - * ... Nothing to expose in this case - * } cached; - * struct { - * ... Nothing to expose in this case - * } loose; - */ - struct { - struct packed_git *pack; - off_t offset; - unsigned int is_delta; - } packed; - } u; -}; - -/* - * Initializer for a "struct object_info" that wants no items. You may - * also memset() the memory to all-zeroes. - */ -#define OBJECT_INFO_INIT { 0 } - -/* Invoke lookup_replace_object() on the given hash */ -#define OBJECT_INFO_LOOKUP_REPLACE 1 -/* Do not retry packed storage after checking packed and loose storage */ -#define OBJECT_INFO_QUICK 8 -/* - * Do not attempt to fetch the object if missing (even if fetch_is_missing is - * nonzero). - */ -#define OBJECT_INFO_SKIP_FETCH_OBJECT 16 -/* - * This is meant for bulk prefetching of missing blobs in a partial - * clone. Implies OBJECT_INFO_SKIP_FETCH_OBJECT and OBJECT_INFO_QUICK - */ -#define OBJECT_INFO_FOR_PREFETCH (OBJECT_INFO_SKIP_FETCH_OBJECT | OBJECT_INFO_QUICK) - -/* Die if object corruption (not just an object being missing) was detected. */ -#define OBJECT_INFO_DIE_IF_CORRUPT 32 - -int oid_object_info_extended(struct repository *r, - const struct object_id *, - struct object_info *, unsigned flags); - -enum { - /* Retry packed storage after checking packed and loose storage */ - HAS_OBJECT_RECHECK_PACKED = (1 << 0), - /* Allow fetching the object in case the repository has a promisor remote. */ - HAS_OBJECT_FETCH_PROMISOR = (1 << 1), -}; - -/* - * Returns 1 if the object exists. This function will not lazily fetch objects - * in a partial clone by default. - */ -int has_object(struct repository *r, const struct object_id *oid, - unsigned flags); - -void assert_oid_type(const struct object_id *oid, enum object_type expect); - -/* - * Enabling the object read lock allows multiple threads to safely call the - * following functions in parallel: repo_read_object_file(), - * read_object_with_reference(), oid_object_info() and oid_object_info_extended(). - * - * obj_read_lock() and obj_read_unlock() may also be used to protect other - * section which cannot execute in parallel with object reading. Since the used - * lock is a recursive mutex, these sections can even contain calls to object - * reading functions. However, beware that in these cases zlib inflation won't - * be performed in parallel, losing performance. - * - * TODO: oid_object_info_extended()'s call stack has a recursive behavior. If - * any of its callees end up calling it, this recursive call won't benefit from - * parallel inflation. - */ -void enable_obj_read_lock(void); -void disable_obj_read_lock(void); - -extern int obj_read_use_lock; -extern pthread_mutex_t obj_read_mutex; - -static inline void obj_read_lock(void) -{ - if(obj_read_use_lock) - pthread_mutex_lock(&obj_read_mutex); -} - -static inline void obj_read_unlock(void) -{ - if(obj_read_use_lock) - pthread_mutex_unlock(&obj_read_mutex); -} -/* Flags for for_each_*_object(). */ -enum for_each_object_flags { - /* Iterate only over local objects, not alternates. */ - FOR_EACH_OBJECT_LOCAL_ONLY = (1<<0), - - /* Only iterate over packs obtained from the promisor remote. */ - FOR_EACH_OBJECT_PROMISOR_ONLY = (1<<1), - - /* - * Visit objects within a pack in packfile order rather than .idx order - */ - FOR_EACH_OBJECT_PACK_ORDER = (1<<2), - - /* Only iterate over packs that are not marked as kept in-core. */ - FOR_EACH_OBJECT_SKIP_IN_CORE_KEPT_PACKS = (1<<3), - - /* Only iterate over packs that do not have .keep files. */ - FOR_EACH_OBJECT_SKIP_ON_DISK_KEPT_PACKS = (1<<4), -}; - - -void *read_object_with_reference(struct repository *r, - const struct object_id *oid, - enum object_type required_type, - unsigned long *size, - struct object_id *oid_ret); - -#endif /* OBJECT_STORE_H */ diff --git a/odb.c b/odb.c new file mode 100644 index 0000000000..d1025ac182 --- /dev/null +++ b/odb.c @@ -0,0 +1,1010 @@ +#define USE_THE_REPOSITORY_VARIABLE + +#include "git-compat-util.h" +#include "abspath.h" +#include "commit-graph.h" +#include "config.h" +#include "dir.h" +#include "environment.h" +#include "gettext.h" +#include "hex.h" +#include "khash.h" +#include "lockfile.h" +#include "loose.h" +#include "object-file-convert.h" +#include "object-file.h" +#include "odb.h" +#include "packfile.h" +#include "path.h" +#include "promisor-remote.h" +#include "quote.h" +#include "replace-object.h" +#include "run-command.h" +#include "setup.h" +#include "strbuf.h" +#include "strvec.h" +#include "submodule.h" +#include "write-or-die.h" + +KHASH_INIT(odb_path_map, const char * /* key: odb_path */, + struct odb_source *, 1, fspathhash, fspatheq) + +/* + * This is meant to hold a *small* number of objects that you would + * want repo_read_object_file() to be able to return, but yet you do not want + * to write them into the object store (e.g. a browse-only + * application). + */ +struct cached_object_entry { + struct object_id oid; + struct cached_object { + enum object_type type; + const void *buf; + unsigned long size; + } value; +}; + +static const struct cached_object *find_cached_object(struct object_database *object_store, + const struct object_id *oid) +{ + static const struct cached_object empty_tree = { + .type = OBJ_TREE, + .buf = "", + }; + const struct cached_object_entry *co = object_store->cached_objects; + + for (size_t i = 0; i < object_store->cached_object_nr; i++, co++) + if (oideq(&co->oid, oid)) + return &co->value; + + if (oid->algo && oideq(oid, hash_algos[oid->algo].empty_tree)) + return &empty_tree; + + return NULL; +} + +int odb_mkstemp(struct strbuf *temp_filename, const char *pattern) +{ + int fd; + /* + * we let the umask do its job, don't try to be more + * restrictive except to remove write permission. + */ + int mode = 0444; + repo_git_path_replace(the_repository, temp_filename, "objects/%s", pattern); + fd = git_mkstemp_mode(temp_filename->buf, mode); + if (0 <= fd) + return fd; + + /* slow path */ + /* some mkstemp implementations erase temp_filename on failure */ + repo_git_path_replace(the_repository, temp_filename, "objects/%s", pattern); + safe_create_leading_directories(the_repository, temp_filename->buf); + return xmkstemp_mode(temp_filename->buf, mode); +} + +/* + * Return non-zero iff the path is usable as an alternate object database. + */ +static int alt_odb_usable(struct object_database *o, + struct strbuf *path, + const char *normalized_objdir, khiter_t *pos) +{ + int r; + + /* Detect cases where alternate disappeared */ + if (!is_directory(path->buf)) { + error(_("object directory %s does not exist; " + "check .git/objects/info/alternates"), + path->buf); + return 0; + } + + /* + * Prevent the common mistake of listing the same + * thing twice, or object directory itself. + */ + if (!o->source_by_path) { + khiter_t p; + + o->source_by_path = kh_init_odb_path_map(); + assert(!o->sources->next); + p = kh_put_odb_path_map(o->source_by_path, o->sources->path, &r); + assert(r == 1); /* never used */ + kh_value(o->source_by_path, p) = o->sources; + } + if (fspatheq(path->buf, normalized_objdir)) + return 0; + *pos = kh_put_odb_path_map(o->source_by_path, path->buf, &r); + /* r: 0 = exists, 1 = never used, 2 = deleted */ + return r == 0 ? 0 : 1; +} + +/* + * Prepare alternate object database registry. + * + * The variable alt_odb_list points at the list of struct + * odb_source. The elements on this list come from + * non-empty elements from colon separated ALTERNATE_DB_ENVIRONMENT + * environment variable, and $GIT_OBJECT_DIRECTORY/info/alternates, + * whose contents is similar to that environment variable but can be + * LF separated. Its base points at a statically allocated buffer that + * contains "/the/directory/corresponding/to/.git/objects/...", while + * its name points just after the slash at the end of ".git/objects/" + * in the example above, and has enough space to hold all hex characters + * of the object ID, an extra slash for the first level indirection, and + * the terminating NUL. + */ +static void read_info_alternates(struct repository *r, + const char *relative_base, + int depth); +static int link_alt_odb_entry(struct repository *r, const struct strbuf *entry, + const char *relative_base, int depth, const char *normalized_objdir) +{ + struct odb_source *alternate; + struct strbuf pathbuf = STRBUF_INIT; + struct strbuf tmp = STRBUF_INIT; + khiter_t pos; + int ret = -1; + + if (!is_absolute_path(entry->buf) && relative_base) { + strbuf_realpath(&pathbuf, relative_base, 1); + strbuf_addch(&pathbuf, '/'); + } + strbuf_addbuf(&pathbuf, entry); + + if (!strbuf_realpath(&tmp, pathbuf.buf, 0)) { + error(_("unable to normalize alternate object path: %s"), + pathbuf.buf); + goto error; + } + strbuf_swap(&pathbuf, &tmp); + + /* + * The trailing slash after the directory name is given by + * this function at the end. Remove duplicates. + */ + while (pathbuf.len && pathbuf.buf[pathbuf.len - 1] == '/') + strbuf_setlen(&pathbuf, pathbuf.len - 1); + + if (!alt_odb_usable(r->objects, &pathbuf, normalized_objdir, &pos)) + goto error; + + CALLOC_ARRAY(alternate, 1); + /* pathbuf.buf is already in r->objects->source_by_path */ + alternate->path = strbuf_detach(&pathbuf, NULL); + + /* add the alternate entry */ + *r->objects->sources_tail = alternate; + r->objects->sources_tail = &(alternate->next); + alternate->next = NULL; + assert(r->objects->source_by_path); + kh_value(r->objects->source_by_path, pos) = alternate; + + /* recursively add alternates */ + read_info_alternates(r, alternate->path, depth + 1); + ret = 0; + error: + strbuf_release(&tmp); + strbuf_release(&pathbuf); + return ret; +} + +static const char *parse_alt_odb_entry(const char *string, + int sep, + struct strbuf *out) +{ + const char *end; + + strbuf_reset(out); + + if (*string == '#') { + /* comment; consume up to next separator */ + end = strchrnul(string, sep); + } else if (*string == '"' && !unquote_c_style(out, string, &end)) { + /* + * quoted path; unquote_c_style has copied the + * data for us and set "end". Broken quoting (e.g., + * an entry that doesn't end with a quote) falls + * back to the unquoted case below. + */ + } else { + /* normal, unquoted path */ + end = strchrnul(string, sep); + strbuf_add(out, string, end - string); + } + + if (*end) + end++; + return end; +} + +static void link_alt_odb_entries(struct repository *r, const char *alt, + int sep, const char *relative_base, int depth) +{ + struct strbuf objdirbuf = STRBUF_INIT; + struct strbuf entry = STRBUF_INIT; + + if (!alt || !*alt) + return; + + if (depth > 5) { + error(_("%s: ignoring alternate object stores, nesting too deep"), + relative_base); + return; + } + + strbuf_realpath(&objdirbuf, r->objects->sources->path, 1); + + while (*alt) { + alt = parse_alt_odb_entry(alt, sep, &entry); + if (!entry.len) + continue; + link_alt_odb_entry(r, &entry, + relative_base, depth, objdirbuf.buf); + } + strbuf_release(&entry); + strbuf_release(&objdirbuf); +} + +static void read_info_alternates(struct repository *r, + const char *relative_base, + int depth) +{ + char *path; + struct strbuf buf = STRBUF_INIT; + + path = xstrfmt("%s/info/alternates", relative_base); + if (strbuf_read_file(&buf, path, 1024) < 0) { + warn_on_fopen_errors(path); + free(path); + return; + } + + link_alt_odb_entries(r, buf.buf, '\n', relative_base, depth); + strbuf_release(&buf); + free(path); +} + +void add_to_alternates_file(const char *reference) +{ + struct lock_file lock = LOCK_INIT; + char *alts = repo_git_path(the_repository, "objects/info/alternates"); + FILE *in, *out; + int found = 0; + + hold_lock_file_for_update(&lock, alts, LOCK_DIE_ON_ERROR); + out = fdopen_lock_file(&lock, "w"); + if (!out) + die_errno(_("unable to fdopen alternates lockfile")); + + in = fopen(alts, "r"); + if (in) { + struct strbuf line = STRBUF_INIT; + + while (strbuf_getline(&line, in) != EOF) { + if (!strcmp(reference, line.buf)) { + found = 1; + break; + } + fprintf_or_die(out, "%s\n", line.buf); + } + + strbuf_release(&line); + fclose(in); + } + else if (errno != ENOENT) + die_errno(_("unable to read alternates file")); + + if (found) { + rollback_lock_file(&lock); + } else { + fprintf_or_die(out, "%s\n", reference); + if (commit_lock_file(&lock)) + die_errno(_("unable to move new alternates file into place")); + if (the_repository->objects->loaded_alternates) + link_alt_odb_entries(the_repository, reference, + '\n', NULL, 0); + } + free(alts); +} + +void add_to_alternates_memory(const char *reference) +{ + /* + * Make sure alternates are initialized, or else our entry may be + * overwritten when they are. + */ + prepare_alt_odb(the_repository); + + link_alt_odb_entries(the_repository, reference, + '\n', NULL, 0); +} + +struct odb_source *set_temporary_primary_odb(const char *dir, int will_destroy) +{ + struct odb_source *source; + + /* + * Make sure alternates are initialized, or else our entry may be + * overwritten when they are. + */ + prepare_alt_odb(the_repository); + + /* + * Make a new primary odb and link the old primary ODB in as an + * alternate + */ + source = xcalloc(1, sizeof(*source)); + source->path = xstrdup(dir); + + /* + * Disable ref updates while a temporary odb is active, since + * the objects in the database may roll back. + */ + source->disable_ref_updates = 1; + source->will_destroy = will_destroy; + source->next = the_repository->objects->sources; + the_repository->objects->sources = source; + return source->next; +} + +static void free_object_directory(struct odb_source *source) +{ + free(source->path); + odb_clear_loose_cache(source); + loose_object_map_clear(&source->loose_map); + free(source); +} + +void restore_primary_odb(struct odb_source *restore_alt, const char *old_path) +{ + struct odb_source *cur_alt = the_repository->objects->sources; + + if (strcmp(old_path, cur_alt->path)) + BUG("expected %s as primary object store; found %s", + old_path, cur_alt->path); + + if (cur_alt->next != restore_alt) + BUG("we expect the old primary object store to be the first alternate"); + + the_repository->objects->sources = restore_alt; + free_object_directory(cur_alt); +} + +/* + * Compute the exact path an alternate is at and returns it. In case of + * error NULL is returned and the human readable error is added to `err` + * `path` may be relative and should point to $GIT_DIR. + * `err` must not be null. + */ +char *compute_alternate_path(const char *path, struct strbuf *err) +{ + char *ref_git = NULL; + const char *repo; + int seen_error = 0; + + ref_git = real_pathdup(path, 0); + if (!ref_git) { + seen_error = 1; + strbuf_addf(err, _("path '%s' does not exist"), path); + goto out; + } + + repo = read_gitfile(ref_git); + if (!repo) + repo = read_gitfile(mkpath("%s/.git", ref_git)); + if (repo) { + free(ref_git); + ref_git = xstrdup(repo); + } + + if (!repo && is_directory(mkpath("%s/.git/objects", ref_git))) { + char *ref_git_git = mkpathdup("%s/.git", ref_git); + free(ref_git); + ref_git = ref_git_git; + } else if (!is_directory(mkpath("%s/objects", ref_git))) { + struct strbuf sb = STRBUF_INIT; + seen_error = 1; + if (get_common_dir(&sb, ref_git)) { + strbuf_addf(err, + _("reference repository '%s' as a linked " + "checkout is not supported yet."), + path); + goto out; + } + + strbuf_addf(err, _("reference repository '%s' is not a " + "local repository."), path); + goto out; + } + + if (!access(mkpath("%s/shallow", ref_git), F_OK)) { + strbuf_addf(err, _("reference repository '%s' is shallow"), + path); + seen_error = 1; + goto out; + } + + if (!access(mkpath("%s/info/grafts", ref_git), F_OK)) { + strbuf_addf(err, + _("reference repository '%s' is grafted"), + path); + seen_error = 1; + goto out; + } + +out: + if (seen_error) { + FREE_AND_NULL(ref_git); + } + + return ref_git; +} + +struct odb_source *find_odb(struct repository *r, const char *obj_dir) +{ + struct odb_source *source; + char *obj_dir_real = real_pathdup(obj_dir, 1); + struct strbuf odb_path_real = STRBUF_INIT; + + prepare_alt_odb(r); + for (source = r->objects->sources; source; source = source->next) { + strbuf_realpath(&odb_path_real, source->path, 1); + if (!strcmp(obj_dir_real, odb_path_real.buf)) + break; + } + + free(obj_dir_real); + strbuf_release(&odb_path_real); + + if (!source) + die(_("could not find object directory matching %s"), obj_dir); + return source; +} + +static void fill_alternate_refs_command(struct child_process *cmd, + const char *repo_path) +{ + const char *value; + + if (!git_config_get_value("core.alternateRefsCommand", &value)) { + cmd->use_shell = 1; + + strvec_push(&cmd->args, value); + strvec_push(&cmd->args, repo_path); + } else { + cmd->git_cmd = 1; + + strvec_pushf(&cmd->args, "--git-dir=%s", repo_path); + strvec_push(&cmd->args, "for-each-ref"); + strvec_push(&cmd->args, "--format=%(objectname)"); + + if (!git_config_get_value("core.alternateRefsPrefixes", &value)) { + strvec_push(&cmd->args, "--"); + strvec_split(&cmd->args, value); + } + } + + strvec_pushv(&cmd->env, (const char **)local_repo_env); + cmd->out = -1; +} + +static void read_alternate_refs(const char *path, + alternate_ref_fn *cb, + void *data) +{ + struct child_process cmd = CHILD_PROCESS_INIT; + struct strbuf line = STRBUF_INIT; + FILE *fh; + + fill_alternate_refs_command(&cmd, path); + + if (start_command(&cmd)) + return; + + fh = xfdopen(cmd.out, "r"); + while (strbuf_getline_lf(&line, fh) != EOF) { + struct object_id oid; + const char *p; + + if (parse_oid_hex(line.buf, &oid, &p) || *p) { + warning(_("invalid line while parsing alternate refs: %s"), + line.buf); + break; + } + + cb(&oid, data); + } + + fclose(fh); + finish_command(&cmd); + strbuf_release(&line); +} + +struct alternate_refs_data { + alternate_ref_fn *fn; + void *data; +}; + +static int refs_from_alternate_cb(struct odb_source *alternate, + void *data) +{ + struct strbuf path = STRBUF_INIT; + size_t base_len; + struct alternate_refs_data *cb = data; + + if (!strbuf_realpath(&path, alternate->path, 0)) + goto out; + if (!strbuf_strip_suffix(&path, "/objects")) + goto out; + base_len = path.len; + + /* Is this a git repository with refs? */ + strbuf_addstr(&path, "/refs"); + if (!is_directory(path.buf)) + goto out; + strbuf_setlen(&path, base_len); + + read_alternate_refs(path.buf, cb->fn, cb->data); + +out: + strbuf_release(&path); + return 0; +} + +void for_each_alternate_ref(alternate_ref_fn fn, void *data) +{ + struct alternate_refs_data cb; + cb.fn = fn; + cb.data = data; + foreach_alt_odb(refs_from_alternate_cb, &cb); +} + +int foreach_alt_odb(alt_odb_fn fn, void *cb) +{ + struct odb_source *alternate; + int r = 0; + + prepare_alt_odb(the_repository); + for (alternate = the_repository->objects->sources->next; alternate; alternate = alternate->next) { + r = fn(alternate, cb); + if (r) + break; + } + return r; +} + +void prepare_alt_odb(struct repository *r) +{ + if (r->objects->loaded_alternates) + return; + + link_alt_odb_entries(r, r->objects->alternate_db, PATH_SEP, NULL, 0); + + read_info_alternates(r, r->objects->sources->path, 0); + r->objects->loaded_alternates = 1; +} + +int has_alt_odb(struct repository *r) +{ + prepare_alt_odb(r); + return !!r->objects->sources->next; +} + +int obj_read_use_lock = 0; +pthread_mutex_t obj_read_mutex; + +void enable_obj_read_lock(void) +{ + if (obj_read_use_lock) + return; + + obj_read_use_lock = 1; + init_recursive_mutex(&obj_read_mutex); +} + +void disable_obj_read_lock(void) +{ + if (!obj_read_use_lock) + return; + + obj_read_use_lock = 0; + pthread_mutex_destroy(&obj_read_mutex); +} + +int fetch_if_missing = 1; + +static int do_oid_object_info_extended(struct repository *r, + const struct object_id *oid, + struct object_info *oi, unsigned flags) +{ + static struct object_info blank_oi = OBJECT_INFO_INIT; + const struct cached_object *co; + struct pack_entry e; + int rtype; + const struct object_id *real = oid; + int already_retried = 0; + + + if (flags & OBJECT_INFO_LOOKUP_REPLACE) + real = lookup_replace_object(r, oid); + + if (is_null_oid(real)) + return -1; + + if (!oi) + oi = &blank_oi; + + co = find_cached_object(r->objects, real); + if (co) { + if (oi->typep) + *(oi->typep) = co->type; + if (oi->sizep) + *(oi->sizep) = co->size; + if (oi->disk_sizep) + *(oi->disk_sizep) = 0; + if (oi->delta_base_oid) + oidclr(oi->delta_base_oid, the_repository->hash_algo); + if (oi->contentp) + *oi->contentp = xmemdupz(co->buf, co->size); + oi->whence = OI_CACHED; + return 0; + } + + while (1) { + if (find_pack_entry(r, real, &e)) + break; + + /* Most likely it's a loose object. */ + if (!loose_object_info(r, real, oi, flags)) + return 0; + + /* Not a loose object; someone else may have just packed it. */ + if (!(flags & OBJECT_INFO_QUICK)) { + reprepare_packed_git(r); + if (find_pack_entry(r, real, &e)) + break; + } + + /* + * If r is the_repository, this might be an attempt at + * accessing a submodule object as if it were in the_repository + * (having called add_submodule_odb() on that submodule's ODB). + * If any such ODBs exist, register them and try again. + */ + if (r == the_repository && + register_all_submodule_odb_as_alternates()) + /* We added some alternates; retry */ + continue; + + /* Check if it is a missing object */ + if (fetch_if_missing && repo_has_promisor_remote(r) && + !already_retried && + !(flags & OBJECT_INFO_SKIP_FETCH_OBJECT)) { + promisor_remote_get_direct(r, real, 1); + already_retried = 1; + continue; + } + + if (flags & OBJECT_INFO_DIE_IF_CORRUPT) { + const struct packed_git *p; + if ((flags & OBJECT_INFO_LOOKUP_REPLACE) && !oideq(real, oid)) + die(_("replacement %s not found for %s"), + oid_to_hex(real), oid_to_hex(oid)); + if ((p = has_packed_and_bad(r, real))) + die(_("packed object %s (stored in %s) is corrupt"), + oid_to_hex(real), p->pack_name); + } + return -1; + } + + if (oi == &blank_oi) + /* + * We know that the caller doesn't actually need the + * information below, so return early. + */ + return 0; + rtype = packed_object_info(r, e.p, e.offset, oi); + if (rtype < 0) { + mark_bad_packed_object(e.p, real); + return do_oid_object_info_extended(r, real, oi, 0); + } else if (oi->whence == OI_PACKED) { + oi->u.packed.offset = e.offset; + oi->u.packed.pack = e.p; + oi->u.packed.is_delta = (rtype == OBJ_REF_DELTA || + rtype == OBJ_OFS_DELTA); + } + + return 0; +} + +static int oid_object_info_convert(struct repository *r, + const struct object_id *input_oid, + struct object_info *input_oi, unsigned flags) +{ + const struct git_hash_algo *input_algo = &hash_algos[input_oid->algo]; + int do_die = flags & OBJECT_INFO_DIE_IF_CORRUPT; + enum object_type type; + struct object_id oid, delta_base_oid; + struct object_info new_oi, *oi; + unsigned long size; + void *content; + int ret; + + if (repo_oid_to_algop(r, input_oid, the_hash_algo, &oid)) { + if (do_die) + die(_("missing mapping of %s to %s"), + oid_to_hex(input_oid), the_hash_algo->name); + return -1; + } + + /* Is new_oi needed? */ + oi = input_oi; + if (input_oi && (input_oi->delta_base_oid || input_oi->sizep || + input_oi->contentp)) { + new_oi = *input_oi; + /* Does delta_base_oid need to be converted? */ + if (input_oi->delta_base_oid) + new_oi.delta_base_oid = &delta_base_oid; + /* Will the attributes differ when converted? */ + if (input_oi->sizep || input_oi->contentp) { + new_oi.contentp = &content; + new_oi.sizep = &size; + new_oi.typep = &type; + } + oi = &new_oi; + } + + ret = oid_object_info_extended(r, &oid, oi, flags); + if (ret) + return -1; + if (oi == input_oi) + return ret; + + if (new_oi.contentp) { + struct strbuf outbuf = STRBUF_INIT; + + if (type != OBJ_BLOB) { + ret = convert_object_file(the_repository, &outbuf, + the_hash_algo, input_algo, + content, size, type, !do_die); + free(content); + if (ret == -1) + return -1; + size = outbuf.len; + content = strbuf_detach(&outbuf, NULL); + } + if (input_oi->sizep) + *input_oi->sizep = size; + if (input_oi->contentp) + *input_oi->contentp = content; + else + free(content); + if (input_oi->typep) + *input_oi->typep = type; + } + if (new_oi.delta_base_oid == &delta_base_oid) { + if (repo_oid_to_algop(r, &delta_base_oid, input_algo, + input_oi->delta_base_oid)) { + if (do_die) + die(_("missing mapping of %s to %s"), + oid_to_hex(&delta_base_oid), + input_algo->name); + return -1; + } + } + input_oi->whence = new_oi.whence; + input_oi->u = new_oi.u; + return ret; +} + +int oid_object_info_extended(struct repository *r, const struct object_id *oid, + struct object_info *oi, unsigned flags) +{ + int ret; + + if (oid->algo && (hash_algo_by_ptr(r->hash_algo) != oid->algo)) + return oid_object_info_convert(r, oid, oi, flags); + + obj_read_lock(); + ret = do_oid_object_info_extended(r, oid, oi, flags); + obj_read_unlock(); + return ret; +} + + +/* returns enum object_type or negative */ +int oid_object_info(struct repository *r, + const struct object_id *oid, + unsigned long *sizep) +{ + enum object_type type; + struct object_info oi = OBJECT_INFO_INIT; + + oi.typep = &type; + oi.sizep = sizep; + if (oid_object_info_extended(r, oid, &oi, + OBJECT_INFO_LOOKUP_REPLACE) < 0) + return -1; + return type; +} + +int pretend_object_file(struct repository *repo, + void *buf, unsigned long len, enum object_type type, + struct object_id *oid) +{ + struct cached_object_entry *co; + char *co_buf; + + hash_object_file(repo->hash_algo, buf, len, type, oid); + if (has_object(repo, oid, 0) || + find_cached_object(repo->objects, oid)) + return 0; + + ALLOC_GROW(repo->objects->cached_objects, + repo->objects->cached_object_nr + 1, repo->objects->cached_object_alloc); + co = &repo->objects->cached_objects[repo->objects->cached_object_nr++]; + co->value.size = len; + co->value.type = type; + co_buf = xmalloc(len); + memcpy(co_buf, buf, len); + co->value.buf = co_buf; + oidcpy(&co->oid, oid); + return 0; +} + +/* + * This function dies on corrupt objects; the callers who want to + * deal with them should arrange to call oid_object_info_extended() and give + * error messages themselves. + */ +void *repo_read_object_file(struct repository *r, + const struct object_id *oid, + enum object_type *type, + unsigned long *size) +{ + struct object_info oi = OBJECT_INFO_INIT; + unsigned flags = OBJECT_INFO_DIE_IF_CORRUPT | OBJECT_INFO_LOOKUP_REPLACE; + void *data; + + oi.typep = type; + oi.sizep = size; + oi.contentp = &data; + if (oid_object_info_extended(r, oid, &oi, flags)) + return NULL; + + return data; +} + +void *read_object_with_reference(struct repository *r, + const struct object_id *oid, + enum object_type required_type, + unsigned long *size, + struct object_id *actual_oid_return) +{ + enum object_type type; + void *buffer; + unsigned long isize; + struct object_id actual_oid; + + oidcpy(&actual_oid, oid); + while (1) { + int ref_length = -1; + const char *ref_type = NULL; + + buffer = repo_read_object_file(r, &actual_oid, &type, &isize); + if (!buffer) + return NULL; + if (type == required_type) { + *size = isize; + if (actual_oid_return) + oidcpy(actual_oid_return, &actual_oid); + return buffer; + } + /* Handle references */ + else if (type == OBJ_COMMIT) + ref_type = "tree "; + else if (type == OBJ_TAG) + ref_type = "object "; + else { + free(buffer); + return NULL; + } + ref_length = strlen(ref_type); + + if (ref_length + the_hash_algo->hexsz > isize || + memcmp(buffer, ref_type, ref_length) || + get_oid_hex((char *) buffer + ref_length, &actual_oid)) { + free(buffer); + return NULL; + } + free(buffer); + /* Now we have the ID of the referred-to object in + * actual_oid. Check again. */ + } +} + +int has_object(struct repository *r, const struct object_id *oid, + unsigned flags) +{ + unsigned object_info_flags = 0; + + if (!startup_info->have_repository) + return 0; + if (!(flags & HAS_OBJECT_RECHECK_PACKED)) + object_info_flags |= OBJECT_INFO_QUICK; + if (!(flags & HAS_OBJECT_FETCH_PROMISOR)) + object_info_flags |= OBJECT_INFO_SKIP_FETCH_OBJECT; + + return oid_object_info_extended(r, oid, NULL, object_info_flags) >= 0; +} + +void assert_oid_type(const struct object_id *oid, enum object_type expect) +{ + enum object_type type = oid_object_info(the_repository, oid, NULL); + if (type < 0) + die(_("%s is not a valid object"), oid_to_hex(oid)); + if (type != expect) + die(_("%s is not a valid '%s' object"), oid_to_hex(oid), + type_name(expect)); +} + +struct object_database *odb_new(void) +{ + struct object_database *o = xmalloc(sizeof(*o)); + + memset(o, 0, sizeof(*o)); + INIT_LIST_HEAD(&o->packed_git_mru); + hashmap_init(&o->pack_map, pack_map_entry_cmp, NULL, 0); + pthread_mutex_init(&o->replace_mutex, NULL); + return o; +} + +static void free_object_directories(struct object_database *o) +{ + while (o->sources) { + struct odb_source *next; + + next = o->sources->next; + free_object_directory(o->sources); + o->sources = next; + } + kh_destroy_odb_path_map(o->source_by_path); + o->source_by_path = NULL; +} + +void odb_clear(struct object_database *o) +{ + FREE_AND_NULL(o->alternate_db); + + oidmap_clear(&o->replace_map, 1); + pthread_mutex_destroy(&o->replace_mutex); + + free_commit_graph(o->commit_graph); + o->commit_graph = NULL; + o->commit_graph_attempted = 0; + + free_object_directories(o); + o->sources_tail = NULL; + o->loaded_alternates = 0; + + for (size_t i = 0; i < o->cached_object_nr; i++) + free((char *) o->cached_objects[i].value.buf); + FREE_AND_NULL(o->cached_objects); + + INIT_LIST_HEAD(&o->packed_git_mru); + close_object_store(o); + + /* + * `close_object_store()` only closes the packfiles, but doesn't free + * them. We thus have to do this manually. + */ + for (struct packed_git *p = o->packed_git, *next; p; p = next) { + next = p->next; + free(p); + } + o->packed_git = NULL; + + hashmap_clear(&o->pack_map); +} diff --git a/odb.h b/odb.h new file mode 100644 index 0000000000..6f56b168e4 --- /dev/null +++ b/odb.h @@ -0,0 +1,355 @@ +#ifndef ODB_H +#define ODB_H + +#include "hashmap.h" +#include "object.h" +#include "list.h" +#include "oidset.h" +#include "oidmap.h" +#include "thread-utils.h" + +struct oidmap; +struct oidtree; +struct strbuf; +struct repository; + +/* + * The source is the part of the object database that stores the actual + * objects. It thus encapsulates the logic to read and write the specific + * on-disk format. An object database can have multiple sources: + * + * - The primary source, which is typically located in "$GIT_DIR/objects". + * This is where new objects are usually written to. + * + * - Alternate sources, which are configured via "objects/info/alternates" or + * via the GIT_ALTERNATE_OBJECT_DIRECTORIES environment variable. These + * alternate sources are only used to read objects. + */ +struct odb_source { + struct odb_source *next; + + /* + * Used to store the results of readdir(3) calls when we are OK + * sacrificing accuracy due to races for speed. That includes + * object existence with OBJECT_INFO_QUICK, as well as + * our search for unique abbreviated hashes. Don't use it for tasks + * requiring greater accuracy! + * + * Be sure to call odb_load_loose_cache() before using. + */ + uint32_t loose_objects_subdir_seen[8]; /* 256 bits */ + struct oidtree *loose_objects_cache; + + /* Map between object IDs for loose objects. */ + struct loose_object_map *loose_map; + + /* + * This is a temporary object store created by the tmp_objdir + * facility. Disable ref updates since the objects in the store + * might be discarded on rollback. + */ + int disable_ref_updates; + + /* + * This object store is ephemeral, so there is no need to fsync. + */ + int will_destroy; + + /* + * Path to the source. If this is a relative path, it is relative to + * the current working directory. + */ + char *path; +}; + +void prepare_alt_odb(struct repository *r); +int has_alt_odb(struct repository *r); +char *compute_alternate_path(const char *path, struct strbuf *err); +struct odb_source *find_odb(struct repository *r, const char *obj_dir); +typedef int alt_odb_fn(struct odb_source *, void *); +int foreach_alt_odb(alt_odb_fn, void*); +typedef void alternate_ref_fn(const struct object_id *oid, void *); +void for_each_alternate_ref(alternate_ref_fn, void *); + +/* + * Add the directory to the on-disk alternates file; the new entry will also + * take effect in the current process. + */ +void add_to_alternates_file(const char *dir); + +/* + * Add the directory to the in-memory list of alternates (along with any + * recursive alternates it points to), but do not modify the on-disk alternates + * file. + */ +void add_to_alternates_memory(const char *dir); + +/* + * Replace the current writable object directory with the specified temporary + * object directory; returns the former primary object directory. + */ +struct odb_source *set_temporary_primary_odb(const char *dir, int will_destroy); + +/* + * Restore a previous ODB replaced by set_temporary_main_odb. + */ +void restore_primary_odb(struct odb_source *restore_alternate, const char *old_path); + +struct packed_git; +struct multi_pack_index; +struct cached_object_entry; + +/* + * The object database encapsulates access to objects in a repository. It + * manages one or more sources that store the actual objects which are + * configured via alternates. + */ +struct object_database { + /* + * Set of all object directories; the main directory is first (and + * cannot be NULL after initialization). Subsequent directories are + * alternates. + */ + struct odb_source *sources; + struct odb_source **sources_tail; + struct kh_odb_path_map *source_by_path; + + int loaded_alternates; + + /* + * A list of alternate object directories loaded from the environment; + * this should not generally need to be accessed directly, but will + * populate the "sources" list when prepare_alt_odb() is run. + */ + char *alternate_db; + + /* + * Objects that should be substituted by other objects + * (see git-replace(1)). + */ + struct oidmap replace_map; + unsigned replace_map_initialized : 1; + pthread_mutex_t replace_mutex; /* protect object replace functions */ + + struct commit_graph *commit_graph; + unsigned commit_graph_attempted : 1; /* if loading has been attempted */ + + /* + * private data + * + * should only be accessed directly by packfile.c and midx.c + */ + struct multi_pack_index *multi_pack_index; + + /* + * private data + * + * should only be accessed directly by packfile.c + */ + + struct packed_git *packed_git; + /* A most-recently-used ordered version of the packed_git list. */ + struct list_head packed_git_mru; + + struct { + struct packed_git **packs; + unsigned flags; + } kept_pack_cache; + + /* + * This is meant to hold a *small* number of objects that you would + * want repo_read_object_file() to be able to return, but yet you do not want + * to write them into the object store (e.g. a browse-only + * application). + */ + struct cached_object_entry *cached_objects; + size_t cached_object_nr, cached_object_alloc; + + /* + * A map of packfiles to packed_git structs for tracking which + * packs have been loaded already. + */ + struct hashmap pack_map; + + /* + * A fast, rough count of the number of objects in the repository. + * These two fields are not meant for direct access. Use + * repo_approximate_object_count() instead. + */ + unsigned long approximate_object_count; + unsigned approximate_object_count_valid : 1; + + /* + * Whether packed_git has already been populated with this repository's + * packs. + */ + unsigned packed_git_initialized : 1; +}; + +struct object_database *odb_new(void); +void odb_clear(struct object_database *o); + +/* + * Create a temporary file rooted in the object database directory, or + * die on failure. The filename is taken from "pattern", which should have the + * usual "XXXXXX" trailer, and the resulting filename is written into the + * "template" buffer. Returns the open descriptor. + */ +int odb_mkstemp(struct strbuf *temp_filename, const char *pattern); + +void *repo_read_object_file(struct repository *r, + const struct object_id *oid, + enum object_type *type, + unsigned long *size); + +/* Read and unpack an object file into memory, write memory to an object file */ +int oid_object_info(struct repository *r, const struct object_id *, unsigned long *); + +/* + * Add an object file to the in-memory object store, without writing it + * to disk. + * + * Callers are responsible for calling write_object_file to record the + * object in persistent storage before writing any other new objects + * that reference it. + */ +int pretend_object_file(struct repository *repo, + void *buf, unsigned long len, enum object_type type, + struct object_id *oid); + +struct object_info { + /* Request */ + enum object_type *typep; + unsigned long *sizep; + off_t *disk_sizep; + struct object_id *delta_base_oid; + void **contentp; + + /* Response */ + enum { + OI_CACHED, + OI_LOOSE, + OI_PACKED, + OI_DBCACHED + } whence; + union { + /* + * struct { + * ... Nothing to expose in this case + * } cached; + * struct { + * ... Nothing to expose in this case + * } loose; + */ + struct { + struct packed_git *pack; + off_t offset; + unsigned int is_delta; + } packed; + } u; +}; + +/* + * Initializer for a "struct object_info" that wants no items. You may + * also memset() the memory to all-zeroes. + */ +#define OBJECT_INFO_INIT { 0 } + +/* Invoke lookup_replace_object() on the given hash */ +#define OBJECT_INFO_LOOKUP_REPLACE 1 +/* Do not retry packed storage after checking packed and loose storage */ +#define OBJECT_INFO_QUICK 8 +/* + * Do not attempt to fetch the object if missing (even if fetch_is_missing is + * nonzero). + */ +#define OBJECT_INFO_SKIP_FETCH_OBJECT 16 +/* + * This is meant for bulk prefetching of missing blobs in a partial + * clone. Implies OBJECT_INFO_SKIP_FETCH_OBJECT and OBJECT_INFO_QUICK + */ +#define OBJECT_INFO_FOR_PREFETCH (OBJECT_INFO_SKIP_FETCH_OBJECT | OBJECT_INFO_QUICK) + +/* Die if object corruption (not just an object being missing) was detected. */ +#define OBJECT_INFO_DIE_IF_CORRUPT 32 + +int oid_object_info_extended(struct repository *r, + const struct object_id *, + struct object_info *, unsigned flags); + +enum { + /* Retry packed storage after checking packed and loose storage */ + HAS_OBJECT_RECHECK_PACKED = (1 << 0), + /* Allow fetching the object in case the repository has a promisor remote. */ + HAS_OBJECT_FETCH_PROMISOR = (1 << 1), +}; + +/* + * Returns 1 if the object exists. This function will not lazily fetch objects + * in a partial clone by default. + */ +int has_object(struct repository *r, const struct object_id *oid, + unsigned flags); + +void assert_oid_type(const struct object_id *oid, enum object_type expect); + +/* + * Enabling the object read lock allows multiple threads to safely call the + * following functions in parallel: repo_read_object_file(), + * read_object_with_reference(), oid_object_info() and oid_object_info_extended(). + * + * obj_read_lock() and obj_read_unlock() may also be used to protect other + * section which cannot execute in parallel with object reading. Since the used + * lock is a recursive mutex, these sections can even contain calls to object + * reading functions. However, beware that in these cases zlib inflation won't + * be performed in parallel, losing performance. + * + * TODO: oid_object_info_extended()'s call stack has a recursive behavior. If + * any of its callees end up calling it, this recursive call won't benefit from + * parallel inflation. + */ +void enable_obj_read_lock(void); +void disable_obj_read_lock(void); + +extern int obj_read_use_lock; +extern pthread_mutex_t obj_read_mutex; + +static inline void obj_read_lock(void) +{ + if(obj_read_use_lock) + pthread_mutex_lock(&obj_read_mutex); +} + +static inline void obj_read_unlock(void) +{ + if(obj_read_use_lock) + pthread_mutex_unlock(&obj_read_mutex); +} +/* Flags for for_each_*_object(). */ +enum for_each_object_flags { + /* Iterate only over local objects, not alternates. */ + FOR_EACH_OBJECT_LOCAL_ONLY = (1<<0), + + /* Only iterate over packs obtained from the promisor remote. */ + FOR_EACH_OBJECT_PROMISOR_ONLY = (1<<1), + + /* + * Visit objects within a pack in packfile order rather than .idx order + */ + FOR_EACH_OBJECT_PACK_ORDER = (1<<2), + + /* Only iterate over packs that are not marked as kept in-core. */ + FOR_EACH_OBJECT_SKIP_IN_CORE_KEPT_PACKS = (1<<3), + + /* Only iterate over packs that do not have .keep files. */ + FOR_EACH_OBJECT_SKIP_ON_DISK_KEPT_PACKS = (1<<4), +}; + + +void *read_object_with_reference(struct repository *r, + const struct object_id *oid, + enum object_type required_type, + unsigned long *size, + struct object_id *oid_ret); + +#endif /* ODB_H */ diff --git a/oss-fuzz/fuzz-pack-idx.c b/oss-fuzz/fuzz-pack-idx.c index 609a343ee3..d2a92f34d9 100644 --- a/oss-fuzz/fuzz-pack-idx.c +++ b/oss-fuzz/fuzz-pack-idx.c @@ -1,5 +1,5 @@ #include "git-compat-util.h" -#include "object-store.h" +#include "odb.h" #include "packfile.h" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); diff --git a/pack-bitmap-write.c b/pack-bitmap-write.c index 7f400ee012..37648b5712 100644 --- a/pack-bitmap-write.c +++ b/pack-bitmap-write.c @@ -4,7 +4,7 @@ #include "environment.h" #include "gettext.h" #include "hex.h" -#include "object-store.h" +#include "odb.h" #include "commit.h" #include "diff.h" #include "revision.h" diff --git a/pack-bitmap.c b/pack-bitmap.c index ac6d62b980..a695a794e9 100644 --- a/pack-bitmap.c +++ b/pack-bitmap.c @@ -17,7 +17,7 @@ #include "packfile.h" #include "repository.h" #include "trace2.h" -#include "object-store.h" +#include "odb.h" #include "list-objects-filter-options.h" #include "midx.h" #include "config.h" diff --git a/pack-check.c b/pack-check.c index 874897d6cb..67cb2cf72f 100644 --- a/pack-check.c +++ b/pack-check.c @@ -8,7 +8,7 @@ #include "progress.h" #include "packfile.h" #include "object-file.h" -#include "object-store.h" +#include "odb.h" struct idx_entry { off_t offset; diff --git a/pack-mtimes.c b/pack-mtimes.c index 20900ca88d..8e1f2dec0e 100644 --- a/pack-mtimes.c +++ b/pack-mtimes.c @@ -1,7 +1,7 @@ #include "git-compat-util.h" #include "gettext.h" #include "pack-mtimes.h" -#include "object-store.h" +#include "odb.h" #include "packfile.h" #include "strbuf.h" diff --git a/pack-objects.h b/pack-objects.h index 475a2d67ce..1ac8644201 100644 --- a/pack-objects.h +++ b/pack-objects.h @@ -1,7 +1,7 @@ #ifndef PACK_OBJECTS_H #define PACK_OBJECTS_H -#include "object-store.h" +#include "odb.h" #include "thread-utils.h" #include "pack.h" #include "packfile.h" diff --git a/pack-revindex.c b/pack-revindex.c index ffcde48870..0cc422a1e6 100644 --- a/pack-revindex.c +++ b/pack-revindex.c @@ -1,7 +1,7 @@ #include "git-compat-util.h" #include "gettext.h" #include "pack-revindex.h" -#include "object-store.h" +#include "odb.h" #include "packfile.h" #include "strbuf.h" #include "trace2.h" diff --git a/packfile.c b/packfile.c index 60661ad009..346c2f9ce9 100644 --- a/packfile.c +++ b/packfile.c @@ -19,7 +19,7 @@ #include "tree-walk.h" #include "tree.h" #include "object-file.h" -#include "object-store.h" +#include "odb.h" #include "midx.h" #include "commit-graph.h" #include "pack-revindex.h" diff --git a/packfile.h b/packfile.h index 826eb7f475..53c3b7d3b4 100644 --- a/packfile.h +++ b/packfile.h @@ -3,10 +3,10 @@ #include "list.h" #include "object.h" -#include "object-store.h" +#include "odb.h" #include "oidset.h" -/* in object-store.h */ +/* in odb.h */ struct object_info; struct packed_git { diff --git a/path.c b/path.c index c347829aa6..7f56eaf993 100644 --- a/path.c +++ b/path.c @@ -15,7 +15,7 @@ #include "submodule-config.h" #include "path.h" #include "packfile.h" -#include "object-store.h" +#include "odb.h" #include "lockfile.h" #include "exec-cmd.h" diff --git a/promisor-remote.c b/promisor-remote.c index 9d058586df..2baa286bfd 100644 --- a/promisor-remote.c +++ b/promisor-remote.c @@ -3,7 +3,7 @@ #include "git-compat-util.h" #include "gettext.h" #include "hex.h" -#include "object-store.h" +#include "odb.h" #include "promisor-remote.h" #include "config.h" #include "trace2.h" diff --git a/protocol-caps.c b/protocol-caps.c index 9b8db37a21..3022f69a1b 100644 --- a/protocol-caps.c +++ b/protocol-caps.c @@ -6,7 +6,7 @@ #include "hash.h" #include "hex.h" #include "object.h" -#include "object-store.h" +#include "odb.h" #include "repository.h" #include "string-list.h" #include "strbuf.h" diff --git a/read-cache.c b/read-cache.c index c0bb760ad4..c3fa968676 100644 --- a/read-cache.c +++ b/read-cache.c @@ -20,7 +20,7 @@ #include "refs.h" #include "dir.h" #include "object-file.h" -#include "object-store.h" +#include "odb.h" #include "oid-array.h" #include "tree.h" #include "commit.h" diff --git a/ref-filter.c b/ref-filter.c index 7a274633cf..4ce45440ad 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -12,7 +12,7 @@ #include "refs.h" #include "wildmatch.h" #include "object-name.h" -#include "object-store.h" +#include "odb.h" #include "oid-array.h" #include "repo-settings.h" #include "repository.h" diff --git a/reflog.c b/reflog.c index 15d81ebea9..4f8a3b717c 100644 --- a/reflog.c +++ b/reflog.c @@ -5,7 +5,7 @@ #include "config.h" #include "gettext.h" #include "parse-options.h" -#include "object-store.h" +#include "odb.h" #include "reflog.h" #include "refs.h" #include "revision.h" diff --git a/refs.c b/refs.c index 5f6a386cc9..0ff0e582a6 100644 --- a/refs.c +++ b/refs.c @@ -19,7 +19,7 @@ #include "run-command.h" #include "hook.h" #include "object-name.h" -#include "object-store.h" +#include "odb.h" #include "object.h" #include "path.h" #include "submodule.h" diff --git a/remote.c b/remote.c index 4099183cac..17a842f568 100644 --- a/remote.c +++ b/remote.c @@ -12,7 +12,7 @@ #include "refs.h" #include "refspec.h" #include "object-name.h" -#include "object-store.h" +#include "odb.h" #include "path.h" #include "commit.h" #include "diff.h" diff --git a/replace-object.c b/replace-object.c index f8c5f68837..3eae051074 100644 --- a/replace-object.c +++ b/replace-object.c @@ -2,7 +2,7 @@ #include "gettext.h" #include "hex.h" #include "oidmap.h" -#include "object-store.h" +#include "odb.h" #include "replace-object.h" #include "refs.h" #include "repository.h" diff --git a/replace-object.h b/replace-object.h index 3052e96a62..4c9f2a2383 100644 --- a/replace-object.h +++ b/replace-object.h @@ -3,7 +3,7 @@ #include "oidmap.h" #include "repository.h" -#include "object-store.h" +#include "odb.h" struct replace_object { struct oidmap_entry original; diff --git a/repository.c b/repository.c index 7528beccdd..13426db0f2 100644 --- a/repository.c +++ b/repository.c @@ -1,7 +1,7 @@ #include "git-compat-util.h" #include "abspath.h" #include "repository.h" -#include "object-store.h" +#include "odb.h" #include "config.h" #include "object.h" #include "lockfile.h" diff --git a/rerere.c b/rerere.c index 3cd37c5f0a..951e4bf8b4 100644 --- a/rerere.c +++ b/rerere.c @@ -18,7 +18,7 @@ #include "path.h" #include "pathspec.h" #include "object-file.h" -#include "object-store.h" +#include "odb.h" #include "strmap.h" #define RESOLVED 0 diff --git a/revision.c b/revision.c index 2c36a9c179..cdefe7d6e4 100644 --- a/revision.c +++ b/revision.c @@ -8,7 +8,7 @@ #include "hex.h" #include "object-name.h" #include "object-file.h" -#include "object-store.h" +#include "odb.h" #include "oidset.h" #include "tag.h" #include "blob.h" diff --git a/send-pack.c b/send-pack.c index 86592ce526..abca2dd38a 100644 --- a/send-pack.c +++ b/send-pack.c @@ -4,7 +4,7 @@ #include "date.h" #include "gettext.h" #include "hex.h" -#include "object-store.h" +#include "odb.h" #include "pkt-line.h" #include "sideband.h" #include "run-command.h" diff --git a/sequencer.c b/sequencer.c index 1ee0abbd45..2432d0a39e 100644 --- a/sequencer.c +++ b/sequencer.c @@ -13,7 +13,7 @@ #include "dir.h" #include "object-file.h" #include "object-name.h" -#include "object-store.h" +#include "odb.h" #include "object.h" #include "pager.h" #include "commit.h" diff --git a/server-info.c b/server-info.c index d6cd20a39d..9bb30d9ab7 100644 --- a/server-info.c +++ b/server-info.c @@ -11,7 +11,7 @@ #include "packfile.h" #include "path.h" #include "object-file.h" -#include "object-store.h" +#include "odb.h" #include "server-info.h" #include "strbuf.h" #include "tempfile.h" diff --git a/shallow.c b/shallow.c index faeeeb45f9..d379756e39 100644 --- a/shallow.c +++ b/shallow.c @@ -5,7 +5,7 @@ #include "repository.h" #include "tempfile.h" #include "lockfile.h" -#include "object-store.h" +#include "odb.h" #include "commit.h" #include "tag.h" #include "pkt-line.h" diff --git a/streaming.c b/streaming.c index 6d6512e2e0..81c42673a2 100644 --- a/streaming.c +++ b/streaming.c @@ -10,7 +10,7 @@ #include "streaming.h" #include "repository.h" #include "object-file.h" -#include "object-store.h" +#include "odb.h" #include "replace-object.h" #include "packfile.h" diff --git a/submodule-config.c b/submodule-config.c index b30d9365fb..9c80f9f7b6 100644 --- a/submodule-config.c +++ b/submodule-config.c @@ -13,7 +13,7 @@ #include "submodule.h" #include "strbuf.h" #include "object-name.h" -#include "object-store.h" +#include "odb.h" #include "parse-options.h" #include "thread-utils.h" #include "tree-walk.h" diff --git a/submodule.c b/submodule.c index ead3fb5dad..9b1018877d 100644 --- a/submodule.c +++ b/submodule.c @@ -27,7 +27,7 @@ #include "parse-options.h" #include "object-file.h" #include "object-name.h" -#include "object-store.h" +#include "odb.h" #include "commit-reach.h" #include "read-cache-ll.h" #include "setup.h" diff --git a/t/helper/test-find-pack.c b/t/helper/test-find-pack.c index 76c2f4eba8..611a13a326 100644 --- a/t/helper/test-find-pack.c +++ b/t/helper/test-find-pack.c @@ -2,7 +2,7 @@ #include "test-tool.h" #include "object-name.h" -#include "object-store.h" +#include "odb.h" #include "packfile.h" #include "parse-options.h" #include "setup.h" diff --git a/t/helper/test-pack-mtimes.c b/t/helper/test-pack-mtimes.c index fdf1b13437..d51aaa3dc4 100644 --- a/t/helper/test-pack-mtimes.c +++ b/t/helper/test-pack-mtimes.c @@ -3,7 +3,7 @@ #include "test-tool.h" #include "hex.h" #include "strbuf.h" -#include "object-store.h" +#include "odb.h" #include "packfile.h" #include "pack-mtimes.h" #include "setup.h" diff --git a/t/helper/test-partial-clone.c b/t/helper/test-partial-clone.c index 34f1aee558..dba227259a 100644 --- a/t/helper/test-partial-clone.c +++ b/t/helper/test-partial-clone.c @@ -1,7 +1,7 @@ #include "test-tool.h" #include "hex.h" #include "repository.h" -#include "object-store.h" +#include "odb.h" #include "setup.h" /* diff --git a/t/helper/test-read-graph.c b/t/helper/test-read-graph.c index 53b633e2ba..ef5339bbee 100644 --- a/t/helper/test-read-graph.c +++ b/t/helper/test-read-graph.c @@ -3,7 +3,7 @@ #include "test-tool.h" #include "commit-graph.h" #include "repository.h" -#include "object-store.h" +#include "odb.h" #include "bloom.h" #include "setup.h" diff --git a/t/helper/test-read-midx.c b/t/helper/test-read-midx.c index ac81390899..da2aa036b5 100644 --- a/t/helper/test-read-midx.c +++ b/t/helper/test-read-midx.c @@ -4,7 +4,7 @@ #include "hex.h" #include "midx.h" #include "repository.h" -#include "object-store.h" +#include "odb.h" #include "pack-bitmap.h" #include "packfile.h" #include "setup.h" diff --git a/t/helper/test-ref-store.c b/t/helper/test-ref-store.c index 4cfc7c90b5..2920ca59d7 100644 --- a/t/helper/test-ref-store.c +++ b/t/helper/test-ref-store.c @@ -5,7 +5,7 @@ #include "refs.h" #include "setup.h" #include "worktree.h" -#include "object-store.h" +#include "odb.h" #include "path.h" #include "repository.h" #include "strbuf.h" diff --git a/tag.c b/tag.c index 05be39067c..5f6868bf7b 100644 --- a/tag.c +++ b/tag.c @@ -5,7 +5,7 @@ #include "environment.h" #include "tag.h" #include "object-name.h" -#include "object-store.h" +#include "odb.h" #include "commit.h" #include "tree.h" #include "blob.h" diff --git a/tmp-objdir.c b/tmp-objdir.c index 056484404b..bef2f917cd 100644 --- a/tmp-objdir.c +++ b/tmp-objdir.c @@ -10,7 +10,7 @@ #include "strbuf.h" #include "strvec.h" #include "quote.h" -#include "object-store.h" +#include "odb.h" #include "repository.h" struct tmp_objdir { diff --git a/tree-walk.c b/tree-walk.c index 90655d5237..34b0fff487 100644 --- a/tree-walk.c +++ b/tree-walk.c @@ -6,7 +6,7 @@ #include "gettext.h" #include "hex.h" #include "object-file.h" -#include "object-store.h" +#include "odb.h" #include "trace2.h" #include "tree.h" #include "pathspec.h" diff --git a/tree.c b/tree.c index b85f56267f..341b7c2ff3 100644 --- a/tree.c +++ b/tree.c @@ -4,7 +4,7 @@ #include "hex.h" #include "tree.h" #include "object-name.h" -#include "object-store.h" +#include "odb.h" #include "commit.h" #include "alloc.h" #include "tree-walk.h" diff --git a/unpack-trees.c b/unpack-trees.c index 471837f032..f38c761ab9 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -26,7 +26,7 @@ #include "symlinks.h" #include "trace2.h" #include "fsmonitor.h" -#include "object-store.h" +#include "odb.h" #include "promisor-remote.h" #include "entry.h" #include "parallel-checkout.h" diff --git a/upload-pack.c b/upload-pack.c index 26f29b85b5..e994d6a901 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -10,7 +10,7 @@ #include "pkt-line.h" #include "sideband.h" #include "repository.h" -#include "object-store.h" +#include "odb.h" #include "oid-array.h" #include "object.h" #include "commit.h" diff --git a/walker.c b/walker.c index b470d43e54..a8abe8a2e7 100644 --- a/walker.c +++ b/walker.c @@ -5,7 +5,7 @@ #include "hex.h" #include "walker.h" #include "repository.h" -#include "object-store.h" +#include "odb.h" #include "commit.h" #include "strbuf.h" #include "tree.h" diff --git a/xdiff-interface.c b/xdiff-interface.c index 1edcd319e6..01e6e378ea 100644 --- a/xdiff-interface.c +++ b/xdiff-interface.c @@ -5,7 +5,7 @@ #include "gettext.h" #include "config.h" #include "hex.h" -#include "object-store.h" +#include "odb.h" #include "strbuf.h" #include "xdiff-interface.h" #include "xdiff/xtypes.h" -- cgit v1.2.3