]> git.ipfire.org Git - thirdparty/git.git/commitdiff
connect: parse v2 refs with correct hash algorithm
authorbrian m. carlson <sandals@crustytoothpaste.net>
Mon, 25 May 2020 19:59:16 +0000 (19:59 +0000)
committerJunio C Hamano <gitster@pobox.com>
Wed, 27 May 2020 17:07:07 +0000 (10:07 -0700)
When using protocol v2, we need to know what hash algorithm is used by
the remote end.  See if the server has sent us an object-format
capability, and if so, use it to determine the hash algorithm in use and
set that value in the packet reader.  Parse the refs using this
algorithm.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
connect.c

index 1d05bc56eda2e61af069bd8200f6e1a9f082be3f..66650ff2d3349213ac34a9600516d656063c97c9 100644 (file)
--- a/connect.c
+++ b/connect.c
@@ -283,7 +283,7 @@ static int process_ref(const struct packet_reader *reader, int len,
                die(_("protocol error: unexpected capabilities^{}"));
        } else if (check_ref(name, flags)) {
                struct ref *ref = alloc_ref(name);
-               memcpy(ref->old_oid.hash, old_oid.hash, reader->hash_algo->rawsz);
+               oidcpy(&ref->old_oid, &old_oid);
                **list = ref;
                *list = &ref->next;
        }
@@ -395,7 +395,7 @@ static int process_ref_v2(struct packet_reader *reader, struct ref ***list)
                goto out;
        }
 
-       if (parse_oid_hex(line_sections.items[i++].string, &old_oid, &end) ||
+       if (parse_oid_hex_algop(line_sections.items[i++].string, &old_oid, &end, reader->hash_algo) ||
            *end) {
                ret = 0;
                goto out;
@@ -403,7 +403,7 @@ static int process_ref_v2(struct packet_reader *reader, struct ref ***list)
 
        ref = alloc_ref(line_sections.items[i++].string);
 
-       oidcpy(&ref->old_oid, &old_oid);
+       memcpy(ref->old_oid.hash, old_oid.hash, reader->hash_algo->rawsz);
        **list = ref;
        *list = &ref->next;
 
@@ -416,7 +416,8 @@ static int process_ref_v2(struct packet_reader *reader, struct ref ***list)
                        struct object_id peeled_oid;
                        char *peeled_name;
                        struct ref *peeled;
-                       if (parse_oid_hex(arg, &peeled_oid, &end) || *end) {
+                       if (parse_oid_hex_algop(arg, &peeled_oid, &end,
+                                               reader->hash_algo) || *end) {
                                ret = 0;
                                goto out;
                        }
@@ -424,7 +425,8 @@ static int process_ref_v2(struct packet_reader *reader, struct ref ***list)
                        peeled_name = xstrfmt("%s^{}", ref->name);
                        peeled = alloc_ref(peeled_name);
 
-                       oidcpy(&peeled->old_oid, &peeled_oid);
+                       memcpy(peeled->old_oid.hash, peeled_oid.hash,
+                              reader->hash_algo->rawsz);
                        **list = peeled;
                        *list = &peeled->next;
 
@@ -443,6 +445,7 @@ struct ref **get_remote_refs(int fd_out, struct packet_reader *reader,
                             const struct string_list *server_options)
 {
        int i;
+       const char *hash_name;
        *list = NULL;
 
        if (server_supports_v2("ls-refs", 1))
@@ -451,6 +454,14 @@ struct ref **get_remote_refs(int fd_out, struct packet_reader *reader,
        if (server_supports_v2("agent", 0))
                packet_write_fmt(fd_out, "agent=%s", git_user_agent_sanitized());
 
+       if (server_feature_v2("object-format", &hash_name)) {
+               int hash_algo = hash_algo_by_name(hash_name);
+               if (hash_algo == GIT_HASH_UNKNOWN)
+                       die(_("unknown object format '%s' specified by server"), hash_name);
+               reader->hash_algo = &hash_algos[hash_algo];
+               packet_write_fmt(fd_out, "object-format=%s", reader->hash_algo->name);
+       }
+
        if (server_options && server_options->nr &&
            server_supports_v2("server-option", 1))
                for (i = 0; i < server_options->nr; i++)