]> git.ipfire.org Git - thirdparty/git.git/commitdiff
odb: get rid of `the_repository` when handling alternates
authorPatrick Steinhardt <ps@pks.im>
Thu, 5 Jun 2025 06:46:58 +0000 (08:46 +0200)
committerJunio C Hamano <gitster@pobox.com>
Thu, 5 Jun 2025 15:51:59 +0000 (08:51 -0700)
The functions to manage alternates all depend on `the_repository`.
Refactor them to accept an object database as parameter and adjusting
all callers. The functions are renamed accordingly.

Note that right now the situation is still somewhat weird because we end
up using the path provided by the object store's repository anyway. This
will be adapted over time though so that we instead store the path to
the primary object directory in the object database itself.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
14 files changed:
builtin/clone.c
builtin/fsck.c
builtin/grep.c
builtin/repack.c
commit-graph.c
loose.c
object-file.c
object-name.c
odb.c
odb.h
packfile.c
submodule.c
t/helper/test-ref-store.c
tmp-objdir.c

index 1eafeefb48d1fc95b6d91ff7297a0aa02474cb62..3aabdf6570b71b7def7da697d23c4922f3b3c878 100644 (file)
@@ -171,7 +171,7 @@ static int add_one_reference(struct string_list_item *item, void *cb_data)
        } else {
                struct strbuf sb = STRBUF_INIT;
                strbuf_addf(&sb, "%s/objects", ref_git);
-               add_to_alternates_file(sb.buf);
+               odb_add_to_alternates_file(the_repository->objects, sb.buf);
                strbuf_release(&sb);
        }
 
@@ -212,12 +212,14 @@ static void copy_alternates(struct strbuf *src, const char *src_repo)
                if (!line.len || line.buf[0] == '#')
                        continue;
                if (is_absolute_path(line.buf)) {
-                       add_to_alternates_file(line.buf);
+                       odb_add_to_alternates_file(the_repository->objects,
+                                                  line.buf);
                        continue;
                }
                abs_path = mkpathdup("%s/objects/%s", src_repo, line.buf);
                if (!normalize_path_copy(abs_path, abs_path))
-                       add_to_alternates_file(abs_path);
+                       odb_add_to_alternates_file(the_repository->objects,
+                                                  abs_path);
                else
                        warning("skipping invalid relative alternate: %s/%s",
                                src_repo, line.buf);
@@ -352,7 +354,7 @@ static void clone_local(const char *src_repo, const char *dest_repo)
                struct strbuf alt = STRBUF_INIT;
                get_common_dir(&alt, src_repo);
                strbuf_addstr(&alt, "/objects");
-               add_to_alternates_file(alt.buf);
+               odb_add_to_alternates_file(the_repository->objects, alt.buf);
                strbuf_release(&alt);
        } else {
                struct strbuf src = STRBUF_INIT;
index 9abd7b255808a08942e0a0d378bfb3c526c3aa88..014aa1344e26b4b950508b462011bebfd9b39c15 100644 (file)
@@ -997,7 +997,7 @@ int cmd_fsck(int argc,
                for_each_packed_object(the_repository,
                                       mark_packed_for_connectivity, NULL, 0);
        } else {
-               prepare_alt_odb(the_repository);
+               odb_prepare_alternates(the_repository->objects);
                for (source = the_repository->objects->sources; source; source = source->next)
                        fsck_object_dir(source->path);
 
@@ -1108,7 +1108,7 @@ int cmd_fsck(int argc,
        if (the_repository->settings.core_commit_graph) {
                struct child_process commit_graph_verify = CHILD_PROCESS_INIT;
 
-               prepare_alt_odb(the_repository);
+               odb_prepare_alternates(the_repository->objects);
                for (source = the_repository->objects->sources; source; source = source->next) {
                        child_process_init(&commit_graph_verify);
                        commit_graph_verify.git_cmd = 1;
@@ -1126,7 +1126,7 @@ int cmd_fsck(int argc,
        if (the_repository->settings.core_multi_pack_index) {
                struct child_process midx_verify = CHILD_PROCESS_INIT;
 
-               prepare_alt_odb(the_repository);
+               odb_prepare_alternates(the_repository->objects);
                for (source = the_repository->objects->sources; source; source = source->next) {
                        child_process_init(&midx_verify);
                        midx_verify.git_cmd = 1;
index a1d7ee7af39687e0aa486e7f6ee0840a148fdee4..336cfcab6fbce8bc77c52b1674de07c6c39b2ce4 100644 (file)
@@ -462,7 +462,7 @@ static int grep_submodule(struct grep_opt *opt,
 
        /*
         * NEEDSWORK: repo_read_gitmodules() might call
-        * add_to_alternates_memory() via config_from_gitmodules(). This
+        * odb_add_to_alternates_memory() via config_from_gitmodules(). This
         * operation causes a race condition with concurrent object readings
         * performed by the worker threads. That's why we need obj_read_lock()
         * here. It should be removed once it's no longer necessary to add the
index 167823200586fba3b877529efaa024a4498e7052..8145474cf8d98b5e561487a6f5ecb2444c4cfb7a 100644 (file)
@@ -1256,7 +1256,8 @@ int cmd_repack(int argc,
        if (write_bitmaps && !(pack_everything & ALL_INTO_ONE) && !write_midx)
                die(_(incremental_bitmap_conflict_error));
 
-       if (write_bitmaps && po_args.local && has_alt_odb(the_repository)) {
+       if (write_bitmaps && po_args.local &&
+           odb_has_alternates(the_repository->objects)) {
                /*
                 * When asked to do a local repack, but we have
                 * packfiles that are inherited from an alternate, then
index 6ced5b366e71014b4027e2564ecf2715de36b045..59265f89385a397fde3d929d083d4b3cbe45c8bb 100644 (file)
@@ -649,7 +649,7 @@ struct commit_graph *load_commit_graph_chain_fd_st(struct repository *r,
        count = st->st_size / (the_hash_algo->hexsz + 1);
        CALLOC_ARRAY(oids, count);
 
-       prepare_alt_odb(r);
+       odb_prepare_alternates(r->objects);
 
        for (i = 0; i < count; i++) {
                struct odb_source *source;
@@ -778,7 +778,7 @@ static int prepare_commit_graph(struct repository *r)
        if (!commit_graph_compatible(r))
                return 0;
 
-       prepare_alt_odb(r);
+       odb_prepare_alternates(r->objects);
        for (source = r->objects->sources;
             !r->objects->commit_graph && source;
             source = source->next)
diff --git a/loose.c b/loose.c
index fab4041c03d50bc49fa81c149c0157bc9c024dfe..519f5db79352a11bfb38e2a913749be9eacabd7b 100644 (file)
--- a/loose.c
+++ b/loose.c
@@ -112,7 +112,7 @@ int repo_read_loose_object_map(struct repository *repo)
        if (!should_use_loose_object_map(repo))
                return 0;
 
-       prepare_alt_odb(repo);
+       odb_prepare_alternates(repo->objects);
 
        for (source = repo->objects->sources; source; source = source->next) {
                if (load_one_loose_object_map(repo, source) < 0) {
index 2d3af8a77c0f5ba2e4319a725dc3610881cb3fc1..04da19a1a3bd7765d613c08c997cc8c4e2934bf7 100644 (file)
@@ -106,7 +106,7 @@ static int check_and_freshen_nonlocal(const struct object_id *oid, int freshen)
 {
        struct odb_source *source;
 
-       prepare_alt_odb(the_repository);
+       odb_prepare_alternates(the_repository->objects);
        for (source = the_repository->objects->sources->next; source; source = source->next) {
                if (check_and_freshen_odb(source, oid, freshen))
                        return 1;
@@ -205,7 +205,7 @@ static int stat_loose_object(struct repository *r, const struct object_id *oid,
        struct odb_source *source;
        static struct strbuf buf = STRBUF_INIT;
 
-       prepare_alt_odb(r);
+       odb_prepare_alternates(r->objects);
        for (source = r->objects->sources; source; source = source->next) {
                *path = odb_loose_path(source, &buf, oid);
                if (!lstat(*path, st))
@@ -227,7 +227,7 @@ static int open_loose_object(struct repository *r,
        int most_interesting_errno = ENOENT;
        static struct strbuf buf = STRBUF_INIT;
 
-       prepare_alt_odb(r);
+       odb_prepare_alternates(r->objects);
        for (source = r->objects->sources; source; source = source->next) {
                *path = odb_loose_path(source, &buf, oid);
                fd = git_open(*path);
@@ -246,7 +246,7 @@ static int quick_has_loose(struct repository *r,
 {
        struct odb_source *source;
 
-       prepare_alt_odb(r);
+       odb_prepare_alternates(r->objects);
        for (source = r->objects->sources; source; source = source->next) {
                if (oidtree_contains(odb_loose_cache(source, oid), oid))
                        return 1;
@@ -1439,7 +1439,7 @@ int for_each_loose_object(each_loose_object_fn cb, void *data,
 {
        struct odb_source *source;
 
-       prepare_alt_odb(the_repository);
+       odb_prepare_alternates(the_repository->objects);
        for (source = the_repository->objects->sources; source; source = source->next) {
                int r = for_each_loose_file_in_objdir(source->path, cb, NULL,
                                                      NULL, data);
index 544634d0f409f49ab71cacd4619fc35770507b31..381536e900e3650c371055613901ab7b86fb5929 100644 (file)
@@ -376,7 +376,7 @@ static int init_object_disambiguation(struct repository *r,
        ds->hex_pfx[len] = '\0';
        ds->repo = r;
        ds->bin_pfx.algo = algo ? hash_algo_by_ptr(algo) : GIT_HASH_UNKNOWN;
-       prepare_alt_odb(r);
+       odb_prepare_alternates(r->objects);
        return 0;
 }
 
diff --git a/odb.c b/odb.c
index 73410920a882ad6dcd61cedcc168d3190ddac8ea..42862ef7fe70a07ed6eb99fc9878eb94f1cf7404 100644 (file)
--- a/odb.c
+++ b/odb.c
@@ -272,10 +272,11 @@ static void read_info_alternates(struct object_database *odb,
        free(path);
 }
 
-void add_to_alternates_file(const char *reference)
+void odb_add_to_alternates_file(struct object_database *odb,
+                               const char *reference)
 {
        struct lock_file lock = LOCK_INIT;
-       char *alts = repo_git_path(the_repository, "objects/info/alternates");
+       char *alts = repo_git_path(odb->repo, "objects/info/alternates");
        FILE *in, *out;
        int found = 0;
 
@@ -308,22 +309,23 @@ void add_to_alternates_file(const char *reference)
                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->objects, reference,
+               if (odb->loaded_alternates)
+                       link_alt_odb_entries(odb, reference,
                                             '\n', NULL, 0);
        }
        free(alts);
 }
 
-void add_to_alternates_memory(const char *reference)
+void odb_add_to_alternates_memory(struct object_database *odb,
+                                 const char *reference)
 {
        /*
         * Make sure alternates are initialized, or else our entry may be
         * overwritten when they are.
         */
-       prepare_alt_odb(the_repository);
+       odb_prepare_alternates(odb);
 
-       link_alt_odb_entries(the_repository->objects, reference,
+       link_alt_odb_entries(odb, reference,
                             '\n', NULL, 0);
 }
 
@@ -335,7 +337,7 @@ struct odb_source *set_temporary_primary_odb(const char *dir, int will_destroy)
         * Make sure alternates are initialized, or else our entry may be
         * overwritten when they are.
         */
-       prepare_alt_odb(the_repository);
+       odb_prepare_alternates(the_repository->objects);
 
        /*
         * Make a new primary odb and link the old primary ODB in as an
@@ -379,12 +381,6 @@ void restore_primary_odb(struct odb_source *restore_alt, const char *old_path)
        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;
@@ -455,7 +451,7 @@ struct odb_source *odb_find_source(struct object_database *odb, const char *obj_
        char *obj_dir_real = real_pathdup(obj_dir, 1);
        struct strbuf odb_path_real = STRBUF_INIT;
 
-       prepare_alt_odb(odb->repo);
+       odb_prepare_alternates(odb);
        for (source = odb->sources; source; source = source->next) {
                strbuf_realpath(&odb_path_real, source->path, 1);
                if (!strcmp(obj_dir_real, odb_path_real.buf))
@@ -573,7 +569,7 @@ int foreach_alt_odb(alt_odb_fn fn, void *cb)
        struct odb_source *alternate;
        int r = 0;
 
-       prepare_alt_odb(the_repository);
+       odb_prepare_alternates(the_repository->objects);
        for (alternate = the_repository->objects->sources->next; alternate; alternate = alternate->next) {
                r = fn(alternate, cb);
                if (r)
@@ -582,21 +578,21 @@ int foreach_alt_odb(alt_odb_fn fn, void *cb)
        return r;
 }
 
-void prepare_alt_odb(struct repository *r)
+void odb_prepare_alternates(struct object_database *odb)
 {
-       if (r->objects->loaded_alternates)
+       if (odb->loaded_alternates)
                return;
 
-       link_alt_odb_entries(r->objects, r->objects->alternate_db, PATH_SEP, NULL, 0);
+       link_alt_odb_entries(odb, odb->alternate_db, PATH_SEP, NULL, 0);
 
-       read_info_alternates(r->objects, r->objects->sources->path, 0);
-       r->objects->loaded_alternates = 1;
+       read_info_alternates(odb, odb->sources->path, 0);
+       odb->loaded_alternates = 1;
 }
 
-int has_alt_odb(struct repository *r)
+int odb_has_alternates(struct object_database *odb)
 {
-       prepare_alt_odb(r);
-       return !!r->objects->sources->next;
+       odb_prepare_alternates(odb);
+       return !!odb->sources->next;
 }
 
 int obj_read_use_lock = 0;
diff --git a/odb.h b/odb.h
index 5de952608f3a3cdc8ec64e7faad0aa2c17fe7d34..eba16929a81f29e56abf62e198120a6dcdf522f6 100644 (file)
--- a/odb.h
+++ b/odb.h
@@ -13,6 +13,14 @@ struct oidtree;
 struct strbuf;
 struct repository;
 
+/*
+ * 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);
+
 /*
  * 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
@@ -65,27 +73,11 @@ struct odb_source {
        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);
 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.
@@ -124,7 +116,7 @@ struct object_database {
        /*
         * 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.
+        * populate the "sources" list when odb_prepare_alternates() is run.
         */
        char *alternate_db;
 
@@ -209,6 +201,33 @@ struct odb_source *odb_find_source(struct object_database *odb, const char *obj_
 int odb_mkstemp(struct object_database *odb,
                struct strbuf *temp_filename, const char *pattern);
 
+/*
+ * Prepare alternate object sources for the given database by reading
+ * "objects/info/alternates" and opening the respective sources.
+ */
+void odb_prepare_alternates(struct object_database *odb);
+
+/*
+ * Check whether the object database has any alternates. The primary object
+ * source does not count as alternate.
+ */
+int odb_has_alternates(struct object_database *odb);
+
+/*
+ * Add the directory to the on-disk alternates file; the new entry will also
+ * take effect in the current process.
+ */
+void odb_add_to_alternates_file(struct object_database *odb,
+                               const char *dir);
+
+/*
+ * Add the directory to the in-memory list of alternate sources (along with any
+ * recursive alternates it points to), but do not modify the on-disk alternates
+ * file.
+ */
+void odb_add_to_alternates_memory(struct object_database *odb,
+                                 const char *dir);
+
 void *repo_read_object_file(struct repository *r,
                            const struct object_id *oid,
                            enum object_type *type,
index 346c2f9ce9057492c1a151f5c15fa01c994ccd6d..ac0e29e99b9165204b72e1795a1e0f5c9b0cf891 100644 (file)
@@ -1034,7 +1034,7 @@ static void prepare_packed_git(struct repository *r)
        if (r->objects->packed_git_initialized)
                return;
 
-       prepare_alt_odb(r);
+       odb_prepare_alternates(r->objects);
        for (source = r->objects->sources; source; source = source->next) {
                int local = (source == r->objects->sources);
                prepare_multi_pack_index_one(r, source->path, local);
@@ -1059,7 +1059,7 @@ void reprepare_packed_git(struct repository *r)
         * the lifetime of the process.
         */
        r->objects->loaded_alternates = 0;
-       prepare_alt_odb(r);
+       odb_prepare_alternates(r->objects);
 
        for (source = r->objects->sources; source; source = source->next)
                odb_clear_loose_cache(source);
index 9b1018877df8b74c93998a9a6a4a433f5f415422..386be2342307be1073818d21c2e988d8ef3b9554 100644 (file)
@@ -189,7 +189,8 @@ int register_all_submodule_odb_as_alternates(void)
        int ret = added_submodule_odb_paths.nr;
 
        for (i = 0; i < added_submodule_odb_paths.nr; i++)
-               add_to_alternates_memory(added_submodule_odb_paths.items[i].string);
+               odb_add_to_alternates_memory(the_repository->objects,
+                                            added_submodule_odb_paths.items[i].string);
        if (ret) {
                string_list_clear(&added_submodule_odb_paths, 0);
                trace2_data_intmax("submodule", the_repository,
index 2920ca59d72f5323d25bf174dd0d650d022eca42..8d9a271845c4b60fb568a77020e21340e0a759c5 100644 (file)
@@ -79,7 +79,7 @@ static const char **get_store(const char **argv, struct ref_store **refs)
                if (!repo_submodule_path_append(the_repository,
                                                &sb, gitdir, "objects/"))
                        die("computing submodule path failed");
-               add_to_alternates_memory(sb.buf);
+               odb_add_to_alternates_memory(the_repository->objects, sb.buf);
                strbuf_release(&sb);
 
                *refs = repo_get_submodule_ref_store(the_repository, gitdir);
index bef2f917cd2f2a84cc3c3a86e202e21235990b5c..4120badf5ceb939d58f43a2479aa9f3253ca6f65 100644 (file)
@@ -304,7 +304,7 @@ const char **tmp_objdir_env(const struct tmp_objdir *t)
 
 void tmp_objdir_add_as_alternate(const struct tmp_objdir *t)
 {
-       add_to_alternates_memory(t->path.buf);
+       odb_add_to_alternates_memory(t->repo->objects, t->path.buf);
 }
 
 void tmp_objdir_replace_primary_odb(struct tmp_objdir *t, int will_destroy)