connect: parse v2 refs with correct hash algorithm
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>
brian m. carlson committed
May 25, 2020 at 19:59 UTC
ab67235bc4900d8203a1a6b6f33cf8afa845e43e
1 file changed
+16
-5
connect.c
+16
-5
@@ -283,7 +283,7 @@ static int process_ref(const struct packet_reader *reader, int len,
283
die(_("protocol error: unexpected capabilities^{}"));
284
} else if (check_ref(name, flags)) {
285
struct ref *ref = alloc_ref(name);
286
- memcpy(ref->old_oid.hash, old_oid.hash, reader->hash_algo->rawsz);
286
+ oidcpy(&ref->old_oid, &old_oid);
287
**list = ref;
288
*list = &ref->next;
289
}
@@ -395,7 +395,7 @@ static int process_ref_v2(struct packet_reader *reader, struct ref ***list)
395
goto out;
396
}
397
398
- if (parse_oid_hex(line_sections.items[i++].string, &old_oid, &end) ||
398
+ if (parse_oid_hex_algop(line_sections.items[i++].string, &old_oid, &end, reader->hash_algo) ||
399
*end) {
400
ret = 0;
401
goto out;
@@ -403,7 +403,7 @@ static int process_ref_v2(struct packet_reader *reader, struct ref ***list)
403
404
ref = alloc_ref(line_sections.items[i++].string);
405
406
- oidcpy(&ref->old_oid, &old_oid);
406
+ memcpy(ref->old_oid.hash, old_oid.hash, reader->hash_algo->rawsz);
407
**list = ref;
408
*list = &ref->next;
409
@@ -416,7 +416,8 @@ static int process_ref_v2(struct packet_reader *reader, struct ref ***list)
416
struct object_id peeled_oid;
417
char *peeled_name;
418
struct ref *peeled;
419
- if (parse_oid_hex(arg, &peeled_oid, &end) || *end) {
419
+ if (parse_oid_hex_algop(arg, &peeled_oid, &end,
420
+ reader->hash_algo) || *end) {
421
ret = 0;
422
goto out;
423
}
@@ -424,7 +425,8 @@ static int process_ref_v2(struct packet_reader *reader, struct ref ***list)
425
peeled_name = xstrfmt("%s^{}", ref->name);
426
peeled = alloc_ref(peeled_name);
427
427
- oidcpy(&peeled->old_oid, &peeled_oid);
428
+ memcpy(peeled->old_oid.hash, peeled_oid.hash,
429
+ reader->hash_algo->rawsz);
430
**list = peeled;
431
*list = &peeled->next;
432
@@ -443,6 +445,7 @@ struct ref **get_remote_refs(int fd_out, struct packet_reader *reader,
445
const struct string_list *server_options)
446
{
447
int i;
448
+ const char *hash_name;
449
*list = NULL;
450
451
if (server_supports_v2("ls-refs", 1))
@@ -451,6 +454,14 @@ struct ref **get_remote_refs(int fd_out, struct packet_reader *reader,
454
if (server_supports_v2("agent", 0))
455
packet_write_fmt(fd_out, "agent=%s", git_user_agent_sanitized());
456
457
+ if (server_feature_v2("object-format", &hash_name)) {
458
+ int hash_algo = hash_algo_by_name(hash_name);
459
+ if (hash_algo == GIT_HASH_UNKNOWN)
460
+ die(_("unknown object format '%s' specified by server"), hash_name);
461
+ reader->hash_algo = &hash_algos[hash_algo];
462
+ packet_write_fmt(fd_out, "object-format=%s", reader->hash_algo->name);
463
+ }
464
+
465
if (server_options && server_options->nr &&
466
server_supports_v2("server-option", 1))
467
for (i = 0; i < server_options->nr; i++)