git/protocol.c
Jonathan Nieder 11c7f2a30b Revert "fetch: default to protocol version 2"
This reverts commit 684ceae32d.

Users fetching from linux-next and other kernel remotes are reporting
that the limited ref advertisement causes negotiation to reach
MAX_IN_VAIN, resulting in too-large fetches.

Reported-by: Lubomir Rintel <lkundrak@v3.sk>
Reported-by: "Dixit, Ashutosh" <ashutosh.dixit@intel.com>
Reported-by: Jiri Slaby <jslaby@suse.cz>
Reported-by: Konstantin Ryabitsev <konstantin@linuxfoundation.org>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-04-22 11:37:44 -07:00

94 lines
2.4 KiB
C

#include "cache.h"
#include "config.h"
#include "protocol.h"
static enum protocol_version parse_protocol_version(const char *value)
{
if (!strcmp(value, "0"))
return protocol_v0;
else if (!strcmp(value, "1"))
return protocol_v1;
else if (!strcmp(value, "2"))
return protocol_v2;
else
return protocol_unknown_version;
}
enum protocol_version get_protocol_version_config(void)
{
const char *value;
const char *git_test_k = "GIT_TEST_PROTOCOL_VERSION";
const char *git_test_v;
if (!git_config_get_string_const("protocol.version", &value)) {
enum protocol_version version = parse_protocol_version(value);
if (version == protocol_unknown_version)
die("unknown value for config 'protocol.version': %s",
value);
return version;
}
git_test_v = getenv(git_test_k);
if (git_test_v && *git_test_v) {
enum protocol_version env = parse_protocol_version(git_test_v);
if (env == protocol_unknown_version)
die("unknown value for %s: %s", git_test_k, git_test_v);
return env;
}
return protocol_v0;
}
enum protocol_version determine_protocol_version_server(void)
{
const char *git_protocol = getenv(GIT_PROTOCOL_ENVIRONMENT);
enum protocol_version version = protocol_v0;
/*
* Determine which protocol version the client has requested. Since
* multiple 'version' keys can be sent by the client, indicating that
* the client is okay to speak any of them, select the greatest version
* that the client has requested. This is due to the assumption that
* the most recent protocol version will be the most state-of-the-art.
*/
if (git_protocol) {
struct string_list list = STRING_LIST_INIT_DUP;
const struct string_list_item *item;
string_list_split(&list, git_protocol, ':', -1);
for_each_string_list_item(item, &list) {
const char *value;
enum protocol_version v;
if (skip_prefix(item->string, "version=", &value)) {
v = parse_protocol_version(value);
if (v > version)
version = v;
}
}
string_list_clear(&list, 0);
}
return version;
}
enum protocol_version determine_protocol_version_client(const char *server_response)
{
enum protocol_version version = protocol_v0;
if (skip_prefix(server_response, "version ", &server_response)) {
version = parse_protocol_version(server_response);
if (version == protocol_unknown_version)
die("server is speaking an unknown protocol");
if (version == protocol_v0)
die("protocol error: server explicitly said version 0");
}
return version;
}