#include "transport.h"
#include "parse-options.h"
#include "pkt-line.h"
+#include "protocol.h"
#include "sideband.h"
static void create_output_file(const char *output_file)
OPT_END()
};
+ register_allowed_protocol_version(protocol_v0);
+
argc = parse_options(argc, argv, prefix, local_opts, NULL,
PARSE_OPT_KEEP_ALL);
struct refspec rs = REFSPEC_INIT_FETCH;
struct argv_array ref_prefixes = ARGV_ARRAY_INIT;
+ register_allowed_protocol_version(protocol_v2);
+ register_allowed_protocol_version(protocol_v1);
+ register_allowed_protocol_version(protocol_v0);
+
fetch_if_missing = 0;
packet_trace_identity("clone");
fetch_if_missing = 0;
+ register_allowed_protocol_version(protocol_v2);
+ register_allowed_protocol_version(protocol_v1);
+ register_allowed_protocol_version(protocol_v0);
+
packet_trace_identity("fetch-pack");
memset(&args, 0, sizeof(args));
#include "argv-array.h"
#include "utf8.h"
#include "packfile.h"
+#include "protocol.h"
#include "list-objects-filter-options.h"
#include "commit-reach.h"
int prune_tags_ok = 1;
struct argv_array argv_gc_auto = ARGV_ARRAY_INIT;
+ register_allowed_protocol_version(protocol_v2);
+ register_allowed_protocol_version(protocol_v1);
+ register_allowed_protocol_version(protocol_v0);
+
packet_trace_identity("fetch");
fetch_if_missing = 0;
#include "builtin.h"
#include "cache.h"
+#include "protocol.h"
#include "transport.h"
#include "ref-filter.h"
#include "remote.h"
memset(&ref_array, 0, sizeof(ref_array));
+ register_allowed_protocol_version(protocol_v2);
+ register_allowed_protocol_version(protocol_v1);
+ register_allowed_protocol_version(protocol_v0);
+
argc = parse_options(argc, argv, prefix, options, ls_remote_usage,
PARSE_OPT_STOP_AT_NON_OPTION);
dest = argv[0];
#include "config.h"
#include "builtin.h"
#include "parse-options.h"
+#include "protocol.h"
#include "exec-cmd.h"
#include "run-command.h"
#include "sha1-array.h"
struct object_id rebase_fork_point;
int autostash;
+ register_allowed_protocol_version(protocol_v2);
+ register_allowed_protocol_version(protocol_v1);
+ register_allowed_protocol_version(protocol_v0);
+
if (!getenv("GIT_REFLOG_ACTION"))
set_reflog_message(argc, argv);
#include "remote.h"
#include "transport.h"
#include "parse-options.h"
+#include "protocol.h"
#include "submodule.h"
#include "submodule-config.h"
#include "send-pack.h"
OPT_END()
};
+ register_allowed_protocol_version(protocol_v1);
+ register_allowed_protocol_version(protocol_v0);
+
packet_trace_identity("push");
git_config(git_push_config, &flags);
argc = parse_options(argc, argv, prefix, options, push_usage, 0);
packet_trace_identity("receive-pack");
+ register_allowed_protocol_version(protocol_v1);
+ register_allowed_protocol_version(protocol_v0);
+
argc = parse_options(argc, argv, prefix, options, receive_pack_usage, 0);
if (argc > 1)
OPT_END()
};
+ register_allowed_protocol_version(protocol_v1);
+ register_allowed_protocol_version(protocol_v0);
+
git_config(send_pack_config, NULL);
argc = parse_options(argc, argv, prefix, options, send_pack_usage, 0);
if (argc > 0) {
#include "builtin.h"
#include "archive.h"
#include "pkt-line.h"
+#include "protocol.h"
#include "sideband.h"
#include "run-command.h"
#include "argv-array.h"
if (argc == 2 && !strcmp(argv[1], "-h"))
usage(upload_archive_usage);
+ register_allowed_protocol_version(protocol_v0);
+
/*
* Set up sideband subprocess.
*
packet_trace_identity("upload-pack");
read_replace_refs = 0;
+ register_allowed_protocol_version(protocol_v2);
+ register_allowed_protocol_version(protocol_v1);
+ register_allowed_protocol_version(protocol_v0);
+
argc = parse_options(argc, argv, NULL, options, upload_pack_usage, 0);
if (argc != 1)
*/
static struct child_process *git_connect_git(int fd[2], char *hostandport,
const char *path, const char *prog,
- enum protocol_version version,
+ const struct strbuf *version_advert,
int flags)
{
struct child_process *conn;
prog, path, 0,
target_host, 0);
- /* If using a new version put that stuff here after a second null byte */
- if (version > 0) {
- strbuf_addch(&request, '\0');
- strbuf_addf(&request, "version=%d%c",
- version, '\0');
- }
+ /* Add version fields after a second null byte */
+ strbuf_addch(&request, '\0');
+ strbuf_addf(&request, "%s%c", version_advert->buf, '\0');
packet_write(fd[1], request.buf, request.len);
*/
static void push_ssh_options(struct argv_array *args, struct argv_array *env,
enum ssh_variant variant, const char *port,
- enum protocol_version version, int flags)
+ const struct strbuf *version_advert, int flags)
{
- if (variant == VARIANT_SSH &&
- version > 0) {
+ if (variant == VARIANT_SSH) {
argv_array_push(args, "-o");
argv_array_push(args, "SendEnv=" GIT_PROTOCOL_ENVIRONMENT);
- argv_array_pushf(env, GIT_PROTOCOL_ENVIRONMENT "=version=%d",
- version);
+ argv_array_pushf(env, GIT_PROTOCOL_ENVIRONMENT "=%s",
+ version_advert->buf);
}
if (flags & CONNECT_IPV4) {
/* Prepare a child_process for use by Git's SSH-tunneled transport. */
static void fill_ssh_args(struct child_process *conn, const char *ssh_host,
- const char *port, enum protocol_version version,
+ const char *port, const struct strbuf *version_advert,
int flags)
{
const char *ssh;
argv_array_push(&detect.args, ssh);
argv_array_push(&detect.args, "-G");
- push_ssh_options(&detect.args, &detect.env_array,
- VARIANT_SSH, port, version, flags);
+ push_ssh_options(&detect.args, &detect.env_array, VARIANT_SSH,
+ port, version_advert, flags);
argv_array_push(&detect.args, ssh_host);
variant = run_command(&detect) ? VARIANT_SIMPLE : VARIANT_SSH;
}
argv_array_push(&conn->args, ssh);
- push_ssh_options(&conn->args, &conn->env_array, variant, port, version, flags);
+ push_ssh_options(&conn->args, &conn->env_array, variant, port,
+ version_advert, flags);
argv_array_push(&conn->args, ssh_host);
}
{
char *hostandport, *path;
struct child_process *conn;
+ struct strbuf version_advert = STRBUF_INIT;
enum protocol protocol;
- enum protocol_version version = get_protocol_version_config();
- /*
- * NEEDSWORK: If we are trying to use protocol v2 and we are planning
- * to perform a push, then fallback to v0 since the client doesn't know
- * how to push yet using v2.
- */
- if (version == protocol_v2 && !strcmp("git-receive-pack", prog))
- version = protocol_v0;
+ get_client_protocol_version_advertisement(&version_advert);
/* Without this we cannot rely on waitpid() to tell
* what happened to our children.
printf("Diag: path=%s\n", path ? path : "NULL");
conn = NULL;
} else if (protocol == PROTO_GIT) {
- conn = git_connect_git(fd, hostandport, path, prog, version, flags);
+ conn = git_connect_git(fd, hostandport, path, prog,
+ &version_advert, flags);
} else {
struct strbuf cmd = STRBUF_INIT;
const char *const *var;
strbuf_release(&cmd);
return NULL;
}
- fill_ssh_args(conn, ssh_host, port, version, flags);
+ fill_ssh_args(conn, ssh_host, port, &version_advert,
+ flags);
} else {
transport_check_allowed("file");
- if (version > 0) {
- argv_array_pushf(&conn->env_array, GIT_PROTOCOL_ENVIRONMENT "=version=%d",
- version);
- }
+ argv_array_pushf(&conn->env_array,
+ GIT_PROTOCOL_ENVIRONMENT "=%s",
+ version_advert.buf);
}
argv_array_push(&conn->args, cmd.buf);
#include "config.h"
#include "protocol.h"
+static enum protocol_version *allowed_versions;
+static int nr_allowed_versions;
+static int alloc_allowed_versions;
+static int version_registration_locked = 0;
+
+static const char protocol_v0_string[] = "0";
+static const char protocol_v1_string[] = "1";
+static const char protocol_v2_string[] = "2";
+
static enum protocol_version parse_protocol_version(const char *value)
{
- if (!strcmp(value, "0"))
+ if (!strcmp(value, protocol_v0_string))
return protocol_v0;
- else if (!strcmp(value, "1"))
+ else if (!strcmp(value, protocol_v1_string))
return protocol_v1;
- else if (!strcmp(value, "2"))
+ else if (!strcmp(value, protocol_v2_string))
return protocol_v2;
else
return protocol_unknown_version;
}
+/* Return the text representation of a wire protocol version. */
+static const char *format_protocol_version(enum protocol_version version)
+{
+ switch (version) {
+ case protocol_v0:
+ return protocol_v0_string;
+ case protocol_v1:
+ return protocol_v1_string;
+ case protocol_v2:
+ return protocol_v2_string;
+ case protocol_unknown_version:
+ die(_("Unrecognized protocol version"));
+ }
+ die(_("Unrecognized protocol_version"));
+}
+
enum protocol_version get_protocol_version_config(void)
{
const char *value;
return protocol_v0;
}
+void register_allowed_protocol_version(enum protocol_version version)
+{
+ if (version_registration_locked)
+ BUG("late attempt to register an allowed protocol version");
+
+ ALLOC_GROW(allowed_versions, nr_allowed_versions + 1,
+ alloc_allowed_versions);
+ allowed_versions[nr_allowed_versions++] = version;
+}
+
+void register_allowed_protocol_versions_from_env(void)
+{
+ const char *git_protocol = getenv(GIT_PROTOCOL_ENVIRONMENT);
+ const char *version_str;
+ struct string_list version_list = STRING_LIST_INIT_DUP;
+ struct string_list_item *version;
+
+ if (!git_protocol)
+ return;
+
+ string_list_split(&version_list, git_protocol, ':', -1);
+ for_each_string_list_item(version, &version_list) {
+ if (skip_prefix(version->string, "version=", &version_str))
+ register_allowed_protocol_version(
+ parse_protocol_version(version_str));
+ }
+ string_list_clear(&version_list, 0);
+}
+
+static int is_allowed_protocol_version(enum protocol_version version)
+{
+ int i;
+ version_registration_locked = 1;
+ for (i = 0; i < nr_allowed_versions; i++)
+ if (version == allowed_versions[i])
+ return 1;
+ return 0;
+}
+
+void get_client_protocol_version_advertisement(struct strbuf *advert)
+{
+ int i, tmp_nr = nr_allowed_versions;
+ enum protocol_version *tmp_allowed_versions, config_version;
+ strbuf_reset(advert);
+
+ version_registration_locked = 1;
+
+ config_version = get_protocol_version_config();
+ if (config_version == protocol_v0) {
+ strbuf_addstr(advert, "version=0");
+ return;
+ }
+
+ if (tmp_nr > 0) {
+ ALLOC_ARRAY(tmp_allowed_versions, tmp_nr);
+ copy_array(tmp_allowed_versions, allowed_versions, tmp_nr,
+ sizeof(enum protocol_version));
+ } else {
+ ALLOC_ARRAY(tmp_allowed_versions, 1);
+ tmp_nr = 1;
+ tmp_allowed_versions[0] = config_version;
+ }
+
+ if (tmp_allowed_versions[0] != config_version)
+ for (i = 1; i < nr_allowed_versions; i++)
+ if (tmp_allowed_versions[i] == config_version) {
+ SWAP(tmp_allowed_versions[0],
+ tmp_allowed_versions[i]);
+ }
+
+ strbuf_addf(advert, "version=%s",
+ format_protocol_version(tmp_allowed_versions[0]));
+ for (i = 1; i < tmp_nr; i++)
+ strbuf_addf(advert, ":version=%s",
+ format_protocol_version(tmp_allowed_versions[i]));
+
+ free(tmp_allowed_versions);
+}
+
enum protocol_version determine_protocol_version_server(void)
{
const char *git_protocol = getenv(GIT_PROTOCOL_ENVIRONMENT);
/*
* 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.
+ * the client is okay to speak any of them, select the first
+ * recognizable version that the client has requested. This is due to
+ * the assumption that the protocol versions will be listed in
+ * preference order.
*/
if (git_protocol) {
struct string_list list = STRING_LIST_INIT_DUP;
if (skip_prefix(item->string, "version=", &value)) {
v = parse_protocol_version(value);
- if (v > version)
+ if (v != protocol_unknown_version &&
+ is_allowed_protocol_version(v)) {
version = v;
+ break;
+ }
}
}
* 'protocol.version' config. If unconfigured, a value of 'protocol_v0' is
* returned.
*/
-extern enum protocol_version get_protocol_version_config(void);
+enum protocol_version get_protocol_version_config(void);
+
+/*
+ * Register an allowable protocol version for a given operation. Registration
+ * must occur before attempting to advertise a version to a server process.
+ */
+void register_allowed_protocol_version(enum protocol_version version);
+
+/*
+ * Register allowable protocol versions from the GIT_PROTOCOL environment var.
+ */
+void register_allowed_protocol_versions_from_env(void);
+
+/*
+ * Fill a strbuf with a version advertisement string suitable for use in the
+ * GIT_PROTOCOL environment variable or similar version negotiation field.
+ */
+void get_client_protocol_version_advertisement(struct strbuf *advert);
/*
* Used by a server to determine which protocol version should be used based on
* request a particular protocol version, a default of 'protocol_v0' will be
* used.
*/
-extern enum protocol_version determine_protocol_version_server(void);
+enum protocol_version determine_protocol_version_server(void);
/*
* Used by a client to determine which protocol version the server is speaking
* based on the server's initial response.
*/
-extern enum protocol_version determine_protocol_version_client(const char *server_response);
+enum protocol_version determine_protocol_version_client(const char *server_response);
#endif /* PROTOCOL_H */
return 0;
}
+static int get_client_protocol_http_header(const struct strbuf *version_advert,
+ struct strbuf *header)
+{
+ if (version_advert->len > 0) {
+ strbuf_addf(header, GIT_PROTOCOL_HEADER ": %s",
+ version_advert->buf);
+
+ return 1;
+ }
+
+ return 0;
+}
+
static struct discovery *discover_refs(const char *service, int for_push)
{
struct strbuf exp = STRBUF_INIT;
struct strbuf refs_url = STRBUF_INIT;
struct strbuf effective_url = STRBUF_INIT;
struct strbuf protocol_header = STRBUF_INIT;
+ struct strbuf version_advert = STRBUF_INIT;
struct string_list extra_headers = STRING_LIST_INIT_DUP;
struct discovery *last = last_discovery;
int http_ret, maybe_smart = 0;
struct http_get_options http_options;
- enum protocol_version version = get_protocol_version_config();
if (last && !strcmp(service, last->service))
return last;
strbuf_addf(&refs_url, "service=%s", service);
}
- /*
- * NEEDSWORK: If we are trying to use protocol v2 and we are planning
- * to perform a push, then fallback to v0 since the client doesn't know
- * how to push yet using v2.
- */
- if (version == protocol_v2 && !strcmp("git-receive-pack", service))
- version = protocol_v0;
+ get_client_protocol_version_advertisement(&version_advert);
/* Add the extra Git-Protocol header */
- if (get_protocol_http_header(version, &protocol_header))
+ if (get_client_protocol_http_header(&version_advert, &protocol_header))
string_list_append(&extra_headers, protocol_header.buf);
memset(&http_options, 0, sizeof(http_options));
struct strbuf buf = STRBUF_INIT;
int nongit;
+ register_allowed_protocol_versions_from_env();
+
setup_git_directory_gently(&nongit);
if (argc < 2) {
error("remote-curl: usage: git remote-curl <remote> [<url>]");
> Accept: */*
> Accept-Encoding: ENCODINGS
> Pragma: no-cache
+ > Git-Protocol: version=0
< HTTP/1.1 200 OK
< Pragma: no-cache
< Cache-Control: no-cache, max-age=0, must-revalidate
test_expect_success 'daemon log records all attributes' '
cat >expect <<-\EOF &&
Extended attribute "host": localhost
- Extended attribute "protocol": version=1
+ Extended attribute "protocol": version=1:version=2:version=0
EOF
>daemon.log &&
GIT_OVERRIDE_VIRTUAL_HOST=localhost \
test_expect_success 'clone myhost:src uses ssh' '
git clone myhost:src ssh-clone &&
- expect_ssh myhost src
+ expect_ssh "-o SendEnv=GIT_PROTOCOL" myhost src
'
test_expect_success !MINGW,!CYGWIN 'clone local path foo:bar' '
test_expect_success 'bracketed hostnames are still ssh' '
git clone "[myhost:123]:src" ssh-bracket-clone &&
- expect_ssh "-p 123" myhost src
+ expect_ssh "-o SendEnv=GIT_PROTOCOL -p 123" myhost src
'
test_expect_success 'OpenSSH variant passes -4' '
git clone -4 "[myhost:123]:src" ssh-ipv4-clone &&
- expect_ssh "-4 -p 123" myhost src
+ expect_ssh "-o SendEnv=GIT_PROTOCOL -4 -p 123" myhost src
'
test_expect_success 'variant can be overridden' '
GIT_SSH="$TRASH_DIRECTORY/uplink" &&
test_when_finished "GIT_SSH=\"\$TRASH_DIRECTORY/ssh\$X\"" &&
git clone "[myhost:123]:src" ssh-bracket-clone-sshlike-uplink &&
- expect_ssh "-p 123" myhost src
+ expect_ssh "-o SendEnv=GIT_PROTOCOL -p 123" myhost src
'
test_expect_success 'plink is treated specially (as putty)' '
copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink" &&
GIT_SSH_VARIANT=ssh \
git clone "[myhost:123]:src" ssh-bracket-clone-variant-1 &&
- expect_ssh "-p 123" myhost src
+ expect_ssh "-o SendEnv=GIT_PROTOCOL -p 123" myhost src
'
test_expect_success 'ssh.variant overrides plink detection' '
copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink" &&
git -c ssh.variant=ssh \
clone "[myhost:123]:src" ssh-bracket-clone-variant-2 &&
- expect_ssh "-p 123" myhost src
+ expect_ssh "-o SendEnv=GIT_PROTOCOL -p 123" myhost src
'
test_expect_success 'GIT_SSH_VARIANT overrides plink detection to plink' '
}
test_expect_success !MINGW 'clone c:temp is ssl' '
- test_clone_url c:temp c temp
+ test_clone_url c:temp "-o SendEnv=GIT_PROTOCOL" c temp
'
test_expect_success MINGW 'clone c:temp is dos drive' '
for repo in rep rep/home/project 123
do
test_expect_success "clone host:$repo" '
- test_clone_url host:$repo host $repo
+ test_clone_url host:$repo "-o SendEnv=GIT_PROTOCOL" host $repo
'
done
for repo in rep rep/home/project 123
do
test_expect_success "clone [::1]:$repo" '
- test_clone_url [::1]:$repo ::1 "$repo"
+ test_clone_url [::1]:$repo "-o SendEnv=GIT_PROTOCOL" ::1 "$repo"
'
done
#home directory
test_expect_success "clone host:/~repo" '
- test_clone_url host:/~repo host "~repo"
+ test_clone_url host:/~repo "-o SendEnv=GIT_PROTOCOL" host "~repo"
'
test_expect_success "clone [::1]:/~repo" '
- test_clone_url [::1]:/~repo ::1 "~repo"
+ test_clone_url [::1]:/~repo "-o SendEnv=GIT_PROTOCOL" ::1 "~repo"
'
# Corner cases
for tcol in "" :
do
test_expect_success "clone ssh://host.xz$tcol/home/user/repo" '
- test_clone_url "ssh://host.xz$tcol/home/user/repo" host.xz /home/user/repo
+ test_clone_url "ssh://host.xz$tcol/home/user/repo" "-o SendEnv=GIT_PROTOCOL" host.xz /home/user/repo
'
# from home directory
test_expect_success "clone ssh://host.xz$tcol/~repo" '
- test_clone_url "ssh://host.xz$tcol/~repo" host.xz "~repo"
+ test_clone_url "ssh://host.xz$tcol/~repo" "-o SendEnv=GIT_PROTOCOL" host.xz "~repo"
'
done
# with port number
test_expect_success 'clone ssh://host.xz:22/home/user/repo' '
- test_clone_url "ssh://host.xz:22/home/user/repo" "-p 22 host.xz" "/home/user/repo"
+ test_clone_url "ssh://host.xz:22/home/user/repo" "-o SendEnv=GIT_PROTOCOL -p 22 host.xz" "/home/user/repo"
'
# from home directory with port number
test_expect_success 'clone ssh://host.xz:22/~repo' '
- test_clone_url "ssh://host.xz:22/~repo" "-p 22 host.xz" "~repo"
+ test_clone_url "ssh://host.xz:22/~repo" "-o SendEnv=GIT_PROTOCOL -p 22 host.xz" "~repo"
'
#IPv6
do
ehost=$(echo $tuah | sed -e "s/1]:/1]/" | tr -d "[]")
test_expect_success "clone ssh://$tuah/home/user/repo" "
- test_clone_url ssh://$tuah/home/user/repo $ehost /home/user/repo
+ test_clone_url ssh://$tuah/home/user/repo '-o SendEnv=GIT_PROTOCOL' $ehost /home/user/repo
"
done
do
euah=$(echo $tuah | tr -d "[]")
test_expect_success "clone ssh://$tuah/~repo" "
- test_clone_url ssh://$tuah/~repo $euah '~repo'
+ test_clone_url ssh://$tuah/~repo '-o SendEnv=GIT_PROTOCOL' $euah '~repo'
"
done
do
euah=$(echo $tuah | tr -d "[]")
test_expect_success "clone ssh://$tuah:22/home/user/repo" "
- test_clone_url ssh://$tuah:22/home/user/repo '-p 22' $euah /home/user/repo
+ test_clone_url ssh://$tuah:22/home/user/repo '-o SendEnv=GIT_PROTOCOL -p 22' $euah /home/user/repo
"
done
do
euah=$(echo $tuah | tr -d "[]")
test_expect_success "clone ssh://$tuah:22/~repo" "
- test_clone_url ssh://$tuah:22/~repo '-p 22' $euah '~repo'
+ test_clone_url ssh://$tuah:22/~repo '-o SendEnv=GIT_PROTOCOL -p 22' $euah '~repo'
"
done
test_cmp expect actual &&
# Client requested to use protocol v1
- grep "clone> .*\\\0\\\0version=1\\\0$" log &&
+ grep "clone> .*\\\0\\\0version=1.*\\\0$" log &&
# Server responded using protocol v1
grep "clone< version 1" log
'
test_cmp expect actual &&
# Client requested to use protocol v1
- grep "fetch> .*\\\0\\\0version=1\\\0$" log &&
+ grep "fetch> .*\\\0\\\0version=1.*\\\0$" log &&
# Server responded using protocol v1
grep "fetch< version 1" log
'
test_cmp expect actual &&
# Client requested to use protocol v1
- grep "fetch> .*\\\0\\\0version=1\\\0$" log &&
+ grep "fetch> .*\\\0\\\0version=1.*\\\0$" log &&
# Server responded using protocol v1
grep "fetch< version 1" log
'
test_cmp expect actual &&
# Client requested to use protocol v1
- grep "push> .*\\\0\\\0version=1\\\0$" log &&
+ grep "push> .*\\\0\\\0version=1.*\\\0$" log &&
# Server responded using protocol v1
grep "push< version 1" log
'
ls-remote --symref "$GIT_DAEMON_URL/parent" >actual &&
# Client requested to use protocol v2
- grep "git> .*\\\0\\\0version=2\\\0$" log &&
+ grep "git> .*\\\0\\\0version=2.*\\\0$" log &&
# Server responded using protocol v2
grep "git< version 2" log &&
test_cmp expect actual &&
# Client requested to use protocol v2
- grep "clone> .*\\\0\\\0version=2\\\0$" log &&
+ grep "clone> .*\\\0\\\0version=2.*\\\0$" log &&
# Server responded using protocol v2
grep "clone< version 2" log
'
test_cmp expect actual &&
# Client requested to use protocol v2
- grep "fetch> .*\\\0\\\0version=2\\\0$" log &&
+ grep "fetch> .*\\\0\\\0version=2.*\\\0$" log &&
# Server responded using protocol v2
grep "fetch< version 2" log
'
test_cmp expect actual &&
# Client requested to use protocol v2
- grep "fetch> .*\\\0\\\0version=2\\\0$" log &&
+ grep "fetch> .*\\\0\\\0version=2.*\\\0$" log &&
# Server responded using protocol v2
grep "fetch< version 2" log
'
test_when_finished "rm -f log" &&
# Till v2 for push is designed, make sure that if a client has
# protocol.version configured to use v2, that the client instead falls
- # back and uses v0.
+ # back to previous versions.
test_commit -C http_child three &&
git -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" log -1 --format=%s client_branch >expect &&
test_cmp expect actual &&
- # Client didnt request to use protocol v2
- ! grep "Git-Protocol: version=2" log &&
- # Server didnt respond using protocol v2
- ! grep "git< version 2" log
+ # Server responded with version 1
+ grep "git< version 1" log
'
test_expect_success 'when server sends "ready", expect DELIM' '
{
struct helper_data *data = transport->data;
struct strbuf buf = STRBUF_INIT;
+ struct strbuf version_advert = STRBUF_INIT;
struct child_process *helper;
int duped;
int code;
argv_array_pushf(&helper->env_array, "%s=%s",
GIT_DIR_ENVIRONMENT, get_git_dir());
+ get_client_protocol_version_advertisement(&version_advert);
+ if (version_advert.len > 0)
+ argv_array_pushf(&helper->env_array, "%s=%s",
+ GIT_PROTOCOL_ENVIRONMENT, version_advert.buf);
+
code = start_command(helper);
if (code < 0 && errno == ENOENT)
die(_("unable to find remote helper for '%s'"), data->name);