Skip to content

Commit ab67235

Browse files
bk2204gitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 67e9a70 commit ab67235

File tree

1 file changed

+16
-5
lines changed

1 file changed

+16
-5
lines changed

connect.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ static int process_ref(const struct packet_reader *reader, int len,
283283
die(_("protocol error: unexpected capabilities^{}"));
284284
} else if (check_ref(name, flags)) {
285285
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);
287287
**list = ref;
288288
*list = &ref->next;
289289
}
@@ -395,15 +395,15 @@ static int process_ref_v2(struct packet_reader *reader, struct ref ***list)
395395
goto out;
396396
}
397397

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) ||
399399
*end) {
400400
ret = 0;
401401
goto out;
402402
}
403403

404404
ref = alloc_ref(line_sections.items[i++].string);
405405

406-
oidcpy(&ref->old_oid, &old_oid);
406+
memcpy(ref->old_oid.hash, old_oid.hash, reader->hash_algo->rawsz);
407407
**list = ref;
408408
*list = &ref->next;
409409

@@ -416,15 +416,17 @@ static int process_ref_v2(struct packet_reader *reader, struct ref ***list)
416416
struct object_id peeled_oid;
417417
char *peeled_name;
418418
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) {
420421
ret = 0;
421422
goto out;
422423
}
423424

424425
peeled_name = xstrfmt("%s^{}", ref->name);
425426
peeled = alloc_ref(peeled_name);
426427

427-
oidcpy(&peeled->old_oid, &peeled_oid);
428+
memcpy(peeled->old_oid.hash, peeled_oid.hash,
429+
reader->hash_algo->rawsz);
428430
**list = peeled;
429431
*list = &peeled->next;
430432

@@ -443,6 +445,7 @@ struct ref **get_remote_refs(int fd_out, struct packet_reader *reader,
443445
const struct string_list *server_options)
444446
{
445447
int i;
448+
const char *hash_name;
446449
*list = NULL;
447450

448451
if (server_supports_v2("ls-refs", 1))
@@ -451,6 +454,14 @@ struct ref **get_remote_refs(int fd_out, struct packet_reader *reader,
451454
if (server_supports_v2("agent", 0))
452455
packet_write_fmt(fd_out, "agent=%s", git_user_agent_sanitized());
453456

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+
454465
if (server_options && server_options->nr &&
455466
server_supports_v2("server-option", 1))
456467
for (i = 0; i < server_options->nr; i++)

0 commit comments

Comments
 (0)