]> git.ipfire.org Git - thirdparty/git.git/commitdiff
http: refactor subsystem to use `packfile_list`s
authorPatrick Steinhardt <ps@pks.im>
Thu, 30 Oct 2025 10:38:40 +0000 (11:38 +0100)
committerJunio C Hamano <gitster@pobox.com>
Thu, 30 Oct 2025 14:09:52 +0000 (07:09 -0700)
The dumb HTTP protocol directly fetches packfiles from the remote server
and temporarily stores them in a list of packfiles. Those packfiles are
not yet added to the repository's packfile store until we finalize the
whole fetch.

Refactor the code to instead use a `struct packfile_list` to store those
packs. This prepares us for a subsequent change where the `->next`
pointer of `struct packed_git` will go away.

Note that this refactoring creates some temporary duplication of code,
as we now have both `packfile_list_find_oid()` and `find_oid_pack()`.
The latter function will be removed in a subsequent commit though.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
http-push.c
http-walker.c
http.c
http.h
packfile.c
packfile.h

index a1c01e3b9b93a3e2be1311521fc69c2568748cd6..d86ce7711982066c704662f1d55ad8b0a411cbea 100644 (file)
@@ -104,7 +104,7 @@ struct repo {
        int has_info_refs;
        int can_update_info_refs;
        int has_info_packs;
-       struct packed_git *packs;
+       struct packfile_list packs;
        struct remote_lock *locks;
 };
 
@@ -311,7 +311,7 @@ static void start_fetch_packed(struct transfer_request *request)
        struct transfer_request *check_request = request_queue_head;
        struct http_pack_request *preq;
 
-       target = find_oid_pack(&request->obj->oid, repo->packs);
+       target = packfile_list_find_oid(repo->packs.head, &request->obj->oid);
        if (!target) {
                fprintf(stderr, "Unable to fetch %s, will not be able to update server info refs\n", oid_to_hex(&request->obj->oid));
                repo->can_update_info_refs = 0;
@@ -683,7 +683,7 @@ static int add_send_request(struct object *obj, struct remote_lock *lock)
                get_remote_object_list(obj->oid.hash[0]);
        if (obj->flags & (REMOTE | PUSHING))
                return 0;
-       target = find_oid_pack(&obj->oid, repo->packs);
+       target = packfile_list_find_oid(repo->packs.head, &obj->oid);
        if (target) {
                obj->flags |= REMOTE;
                return 0;
index 0f7ae46d7f12c0a53ea7d0ff7139c3bb56313fb6..e886e6486646d17d5b74f4db89b2f27c35d938c5 100644 (file)
@@ -15,7 +15,7 @@
 struct alt_base {
        char *base;
        int got_indices;
-       struct packed_git *packs;
+       struct packfile_list packs;
        struct alt_base *next;
 };
 
@@ -324,11 +324,8 @@ static void process_alternates_response(void *callback_data)
                                } else if (is_alternate_allowed(target.buf)) {
                                        warning("adding alternate object store: %s",
                                                target.buf);
-                                       newalt = xmalloc(sizeof(*newalt));
-                                       newalt->next = NULL;
+                                       CALLOC_ARRAY(newalt, 1);
                                        newalt->base = strbuf_detach(&target, NULL);
-                                       newalt->got_indices = 0;
-                                       newalt->packs = NULL;
 
                                        while (tail->next != NULL)
                                                tail = tail->next;
@@ -435,7 +432,7 @@ static int http_fetch_pack(struct walker *walker, struct alt_base *repo,
 
        if (fetch_indices(walker, repo))
                return -1;
-       target = find_oid_pack(oid, repo->packs);
+       target = packfile_list_find_oid(repo->packs.head, oid);
        if (!target)
                return -1;
        close_pack_index(target);
@@ -584,17 +581,15 @@ static void cleanup(struct walker *walker)
        if (data) {
                alt = data->alt;
                while (alt) {
-                       struct packed_git *pack;
+                       struct packfile_list_entry *e;
 
                        alt_next = alt->next;
 
-                       pack = alt->packs;
-                       while (pack) {
-                               struct packed_git *pack_next = pack->next;
-                               close_pack(pack);
-                               free(pack);
-                               pack = pack_next;
+                       for (e = alt->packs.head; e; e = e->next) {
+                               close_pack(e->pack);
+                               free(e->pack);
                        }
+                       packfile_list_clear(&alt->packs);
 
                        free(alt->base);
                        free(alt);
@@ -612,14 +607,11 @@ struct walker *get_http_walker(const char *url)
        struct walker_data *data = xmalloc(sizeof(struct walker_data));
        struct walker *walker = xmalloc(sizeof(struct walker));
 
-       data->alt = xmalloc(sizeof(*data->alt));
+       CALLOC_ARRAY(data->alt, 1);
        data->alt->base = xstrdup(url);
        for (s = data->alt->base + strlen(data->alt->base) - 1; *s == '/'; --s)
                *s = 0;
 
-       data->alt->got_indices = 0;
-       data->alt->packs = NULL;
-       data->alt->next = NULL;
        data->got_alternates = -1;
 
        walker->corrupt_object_found = 0;
diff --git a/http.c b/http.c
index 17130823f006f2cc351a186cba0030d4c08769bc..41f850db16d19f653e0ac7af2878ed1e34fee22f 100644 (file)
--- a/http.c
+++ b/http.c
@@ -2413,8 +2413,9 @@ static char *fetch_pack_index(unsigned char *hash, const char *base_url)
        return tmp;
 }
 
-static int fetch_and_setup_pack_index(struct packed_git **packs_head,
-       unsigned char *sha1, const char *base_url)
+static int fetch_and_setup_pack_index(struct packfile_list *packs,
+                                     unsigned char *sha1,
+                                     const char *base_url)
 {
        struct packed_git *new_pack, *p;
        char *tmp_idx = NULL;
@@ -2448,12 +2449,11 @@ static int fetch_and_setup_pack_index(struct packed_git **packs_head,
        if (ret)
                return -1;
 
-       new_pack->next = *packs_head;
-       *packs_head = new_pack;
+       packfile_list_prepend(packs, new_pack);
        return 0;
 }
 
-int http_get_info_packs(const char *base_url, struct packed_git **packs_head)
+int http_get_info_packs(const char *base_url, struct packfile_list *packs)
 {
        struct http_get_options options = {0};
        int ret = 0;
@@ -2477,7 +2477,7 @@ int http_get_info_packs(const char *base_url, struct packed_git **packs_head)
                    !parse_oid_hex(data, &oid, &data) &&
                    skip_prefix(data, ".pack", &data) &&
                    (*data == '\n' || *data == '\0')) {
-                       fetch_and_setup_pack_index(packs_head, oid.hash, base_url);
+                       fetch_and_setup_pack_index(packs, oid.hash, base_url);
                } else {
                        data = strchrnul(data, '\n');
                }
@@ -2541,14 +2541,9 @@ cleanup:
 }
 
 void http_install_packfile(struct packed_git *p,
-                          struct packed_git **list_to_remove_from)
+                          struct packfile_list *list_to_remove_from)
 {
-       struct packed_git **lst = list_to_remove_from;
-
-       while (*lst != p)
-               lst = &((*lst)->next);
-       *lst = (*lst)->next;
-
+       packfile_list_remove(list_to_remove_from, p);
        packfile_store_add_pack(the_repository->objects->packfiles, p);
 }
 
diff --git a/http.h b/http.h
index 553e16205ce2014a96a2e005a0036b789c2a5b03..f9d459340476e470e05adf31527ae8e01f590b7a 100644 (file)
--- a/http.h
+++ b/http.h
@@ -2,6 +2,7 @@
 #define HTTP_H
 
 struct packed_git;
+struct packfile_list;
 
 #include "git-zlib.h"
 
@@ -190,7 +191,7 @@ struct curl_slist *http_append_auth_header(const struct credential *c,
 
 /* Helpers for fetching packs */
 int http_get_info_packs(const char *base_url,
-                       struct packed_git **packs_head);
+                       struct packfile_list *packs);
 
 /* Helper for getting Accept-Language header */
 const char *http_get_accept_language_header(void);
@@ -226,7 +227,7 @@ void release_http_pack_request(struct http_pack_request *preq);
  * from http_get_info_packs() and have chosen a specific pack to fetch.
  */
 void http_install_packfile(struct packed_git *p,
-                          struct packed_git **list_to_remove_from);
+                          struct packfile_list *list_to_remove_from);
 
 /* Helpers for fetching object */
 struct http_object_request {
index 4d2d3b674f3fb00e6d550acc24e0a48fce85d507..6aa2ca8ac9ee43b1e9614cc08f788afab2447620 100644 (file)
@@ -121,6 +121,15 @@ void packfile_list_append(struct packfile_list *list, struct packed_git *pack)
        }
 }
 
+struct packed_git *packfile_list_find_oid(struct packfile_list_entry *packs,
+                                         const struct object_id *oid)
+{
+       for (; packs; packs = packs->next)
+               if (find_pack_entry_one(oid, packs->pack))
+                       return packs->pack;
+       return NULL;
+}
+
 void pack_report(struct repository *repo)
 {
        fprintf(stderr,
index 39ed1073e4ad79bb7cdf5426328bab53e7650c41..a53336d722a42b399a7379f06a93f61542dfbd4f 100644 (file)
@@ -65,6 +65,14 @@ void packfile_list_remove(struct packfile_list *list, struct packed_git *pack);
 void packfile_list_prepend(struct packfile_list *list, struct packed_git *pack);
 void packfile_list_append(struct packfile_list *list, struct packed_git *pack);
 
+/*
+ * Find the pack within the "packs" list whose index contains the object
+ * "oid". For general object lookups, you probably don't want this; use
+ * find_pack_entry() instead.
+ */
+struct packed_git *packfile_list_find_oid(struct packfile_list_entry *packs,
+                                         const struct object_id *oid);
+
 /*
  * A store that manages packfiles for a given object database.
  */