]> git.feebdaed.xyz Git - 0xmirror/git.git/commitdiff
odb: resolve relative alternative paths when parsing
authorPatrick Steinhardt <ps@pks.im>
Thu, 11 Dec 2025 09:30:11 +0000 (10:30 +0100)
committerJunio C Hamano <gitster@pobox.com>
Thu, 11 Dec 2025 09:39:35 +0000 (18:39 +0900)
Parsing alternates and resolving potential relative paths is currently
handled in two separate steps. This has the effect that the logic to
retrieve alternates is not entirely self-contained. We want it to be
just that though so that we can eventually move the logic to list
alternates into the `struct odb_source`.

Move the logic to resolve relative alternative paths into
`parse_alternates()`. Besides bringing us a step closer towards the
above goal, it also neatly separates concerns of generating the list of
alternatives and linking them into the object database.

Note that we ignore any errors when the relative path cannot be
resolved. This isn't really a change in behaviour though: if the path
cannot be resolved to a directory then `alt_odb_usable()` still knows to
bail out.

While at it, rename the function to `odb_add_alternate_recursively()` to
more clearly indicate what its intent is and to align it with modern
terminology.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
odb.c

diff --git a/odb.c b/odb.c
index 9785f62cb6be5e183a9c891f231e8d5f9e73eb5b..699bdbffd1e7a3010329ade5c3ef395d013f6f71 100644 (file)
--- a/odb.c
+++ b/odb.c
@@ -159,44 +159,21 @@ static struct odb_source *odb_source_new(struct object_database *odb,
        return source;
 }
 
-static struct odb_source *link_alt_odb_entry(struct object_database *odb,
-                                            const char *dir,
-                                            const char *relative_base,
-                                            int depth)
+static struct odb_source *odb_add_alternate_recursively(struct object_database *odb,
+                                                       const char *source,
+                                                       int depth)
 {
        struct odb_source *alternate = NULL;
-       struct strbuf pathbuf = STRBUF_INIT;
        struct strbuf tmp = STRBUF_INIT;
        khiter_t pos;
        int ret;
 
-       if (!is_absolute_path(dir) && relative_base) {
-               strbuf_realpath(&pathbuf, relative_base, 1);
-               strbuf_addch(&pathbuf, '/');
-       }
-       strbuf_addstr(&pathbuf, dir);
-
-       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);
-
-       strbuf_reset(&tmp);
        strbuf_realpath(&tmp, odb->sources->path, 1);
 
-       if (!alt_odb_usable(odb, pathbuf.buf, tmp.buf))
+       if (!alt_odb_usable(odb, source, tmp.buf))
                goto error;
 
-       alternate = odb_source_new(odb, pathbuf.buf, false);
+       alternate = odb_source_new(odb, source, false);
 
        /* add the alternate entry */
        *odb->sources_tail = alternate;
@@ -212,20 +189,22 @@ static struct odb_source *link_alt_odb_entry(struct object_database *odb,
 
  error:
        strbuf_release(&tmp);
-       strbuf_release(&pathbuf);
        return alternate;
 }
 
 static void parse_alternates(const char *string,
                             int sep,
+                            const char *relative_base,
                             struct strvec *out)
 {
+       struct strbuf pathbuf = STRBUF_INIT;
        struct strbuf buf = STRBUF_INIT;
 
        while (*string) {
                const char *end;
 
                strbuf_reset(&buf);
+               strbuf_reset(&pathbuf);
 
                if (*string == '#') {
                        /* comment; consume up to next separator */
@@ -250,9 +229,30 @@ static void parse_alternates(const char *string,
                if (!buf.len)
                        continue;
 
+               if (!is_absolute_path(buf.buf) && relative_base) {
+                       strbuf_realpath(&pathbuf, relative_base, 1);
+                       strbuf_addch(&pathbuf, '/');
+               }
+               strbuf_addbuf(&pathbuf, &buf);
+
+               strbuf_reset(&buf);
+               if (!strbuf_realpath(&buf, pathbuf.buf, 0)) {
+                       error(_("unable to normalize alternate object path: %s"),
+                             pathbuf.buf);
+                       continue;
+               }
+
+               /*
+                * The trailing slash after the directory name is given by
+                * this function at the end. Remove duplicates.
+                */
+               while (buf.len && buf.buf[buf.len - 1] == '/')
+                       strbuf_setlen(&buf, buf.len - 1);
+
                strvec_push(out, buf.buf);
        }
 
+       strbuf_release(&pathbuf);
        strbuf_release(&buf);
 }
 
@@ -270,10 +270,10 @@ static void link_alt_odb_entries(struct object_database *odb, const char *alt,
                return;
        }
 
-       parse_alternates(alt, sep, &alternates);
+       parse_alternates(alt, sep, relative_base, &alternates);
 
        for (size_t i = 0; i < alternates.nr; i++)
-               link_alt_odb_entry(odb, alternates.v[i], relative_base, depth);
+               odb_add_alternate_recursively(odb, alternates.v[i], depth);
 
        strvec_clear(&alternates);
 }
@@ -348,7 +348,7 @@ struct odb_source *odb_add_to_alternates_memory(struct object_database *odb,
         * overwritten when they are.
         */
        odb_prepare_alternates(odb);
-       return link_alt_odb_entry(odb, dir, NULL, 0);
+       return odb_add_alternate_recursively(odb, dir, 0);
 }
 
 struct odb_source *odb_set_temporary_primary_source(struct object_database *odb,