* Obtains the protocol version from the transport and writes it to * transport->data->version, first connecting if not already connected. * * If the protocol version is one that allows skipping the listing of remote * refs, and must_list_refs is 0, the listing of remote refs is skipped and * this function returns NULL. Otherwise, this function returns the list of * remote refs. */
| 337 | * remote refs. |
| 338 | */ |
| 339 | static struct ref *handshake(struct transport *transport, int for_push, |
| 340 | struct transport_ls_refs_options *options, |
| 341 | int must_list_refs) |
| 342 | { |
| 343 | struct git_transport_data *data = transport->data; |
| 344 | struct ref *refs = NULL; |
| 345 | struct packet_reader reader; |
| 346 | size_t sid_len; |
| 347 | const char *server_sid; |
| 348 | |
| 349 | connect_setup(transport, for_push); |
| 350 | |
| 351 | packet_reader_init(&reader, data->fd[0], NULL, 0, |
| 352 | PACKET_READ_CHOMP_NEWLINE | |
| 353 | PACKET_READ_GENTLE_ON_EOF | |
| 354 | PACKET_READ_DIE_ON_ERR_PACKET); |
| 355 | |
| 356 | data->version = discover_version(&reader); |
| 357 | switch (data->version) { |
| 358 | case protocol_v2: |
| 359 | if ((!transport->server_options || !transport->server_options->nr) && |
| 360 | transport->remote->server_options.nr) |
| 361 | transport->server_options = &transport->remote->server_options; |
| 362 | if (server_feature_v2("session-id", &server_sid)) |
| 363 | trace2_data_string("transfer", NULL, "server-sid", server_sid); |
| 364 | if (must_list_refs) |
| 365 | get_remote_refs(data->fd[1], &reader, &refs, for_push, |
| 366 | options, |
| 367 | transport->server_options, |
| 368 | transport->stateless_rpc); |
| 369 | break; |
| 370 | case protocol_v1: |
| 371 | case protocol_v0: |
| 372 | die_if_server_options(transport); |
| 373 | get_remote_heads(&reader, &refs, |
| 374 | for_push ? REF_NORMAL : 0, |
| 375 | &data->extra_have, |
| 376 | &data->shallow); |
| 377 | server_sid = server_feature_value("session-id", &sid_len); |
| 378 | if (server_sid) { |
| 379 | char *sid = xstrndup(server_sid, sid_len); |
| 380 | trace2_data_string("transfer", NULL, "server-sid", sid); |
| 381 | free(sid); |
| 382 | } |
| 383 | break; |
| 384 | case protocol_unknown_version: |
| 385 | BUG("unknown protocol version"); |
| 386 | } |
| 387 | data->finished_handshake = 1; |
| 388 | transport->hash_algo = reader.hash_algo; |
| 389 | |
| 390 | if (reader.line_peeked) |
| 391 | BUG("buffer must be empty at the end of handshake()"); |
| 392 | |
| 393 | return refs; |
| 394 | } |
| 395 | |
| 396 | static struct ref *get_refs_via_connect(struct transport *transport, int for_push, |
no test coverage detected