diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c index 702c9a3397..d1a4306da3 100644 --- a/builtin/fetch-pack.c +++ b/builtin/fetch-pack.c @@ -213,8 +213,8 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix) int flags = args.verbose ? CONNECT_VERBOSE : 0; if (args.diag_url) flags |= CONNECT_DIAG_URL; - conn = git_connect(fd, dest, args.uploadpack, - flags); + conn = git_connect(fd, dest, "git-upload-pack", + args.uploadpack, flags); if (!conn) return args.diag_url ? 0 : 1; } diff --git a/builtin/send-pack.c b/builtin/send-pack.c index fb5b2bad2c..91c03df3f3 100644 --- a/builtin/send-pack.c +++ b/builtin/send-pack.c @@ -274,7 +274,7 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix) fd[0] = 0; fd[1] = 1; } else { - conn = git_connect(fd, dest, receivepack, + conn = git_connect(fd, dest, "git-receive-pack", receivepack, args.verbose ? CONNECT_VERBOSE : 0); } diff --git a/connect.c b/connect.c index 000865bc33..ed486116ee 100644 --- a/connect.c +++ b/connect.c @@ -1408,6 +1408,7 @@ static void fill_ssh_args(struct child_process *conn, const char *ssh_host, * the connection failed). */ struct child_process *git_connect(int fd[2], const char *url, + const char *name, const char *prog, int flags) { char *hostandport, *path; @@ -1417,10 +1418,11 @@ struct child_process *git_connect(int fd[2], const char *url, /* * 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. + * to perform any operation that doesn't involve upload-pack (i.e., a + * fetch, ls-remote, etc), then fallback to v0 since we don't know how + * to do anything else (like push or remote archive) via v2. */ - if (version == protocol_v2 && !strcmp("git-receive-pack", prog)) + if (version == protocol_v2 && strcmp("git-upload-pack", name)) version = protocol_v0; /* Without this we cannot rely on waitpid() to tell diff --git a/connect.h b/connect.h index b26f7de784..f41a0b4c1f 100644 --- a/connect.h +++ b/connect.h @@ -7,7 +7,7 @@ #define CONNECT_DIAG_URL (1u << 1) #define CONNECT_IPV4 (1u << 2) #define CONNECT_IPV6 (1u << 3) -struct child_process *git_connect(int fd[2], const char *url, const char *prog, int flags); +struct child_process *git_connect(int fd[2], const char *url, const char *name, const char *prog, int flags); int finish_connect(struct child_process *conn); int git_connection_is_socket(struct child_process *conn); int server_supports(const char *feature); diff --git a/remote-curl.c b/remote-curl.c index ed7e3a043a..bf5a0b186f 100644 --- a/remote-curl.c +++ b/remote-curl.c @@ -474,10 +474,11 @@ static struct discovery *discover_refs(const char *service, int for_push) /* * 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. + * to perform any operation that doesn't involve upload-pack (i.e., a + * fetch, ls-remote, etc), then fallback to v0 since we don't know how + * to do anything else (like push or remote archive) via v2. */ - if (version == protocol_v2 && !strcmp("git-receive-pack", service)) + if (version == protocol_v2 && strcmp("git-upload-pack", service)) version = protocol_v0; /* Add the extra Git-Protocol header */ diff --git a/t/t5702-protocol-v2.sh b/t/t5702-protocol-v2.sh index e4db7513f4..71aabe30b7 100755 --- a/t/t5702-protocol-v2.sh +++ b/t/t5702-protocol-v2.sh @@ -728,6 +728,33 @@ test_expect_success 'file:// --negotiate-only with protocol v0' ' test_i18ngrep "negotiate-only requires protocol v2" err ' +test_expect_success 'push with custom path does not request v2' ' + rm -f env.trace && + git -C client push \ + --receive-pack="env >../env.trace; git-receive-pack" \ + origin HEAD:refs/heads/custom-push-test && + test_path_is_file env.trace && + ! grep ^GIT_PROTOCOL env.trace +' + +test_expect_success 'fetch with custom path does request v2' ' + rm -f env.trace && + git -C client fetch \ + --upload-pack="env >../env.trace; git-upload-pack" \ + origin HEAD && + grep ^GIT_PROTOCOL=version=2 env.trace +' + +test_expect_success 'archive with custom path does not request v2' ' + rm -f env.trace && + git -C client archive \ + --exec="env >../env.trace; git-upload-archive" \ + --remote=origin \ + HEAD >/dev/null && + test_path_is_file env.trace && + ! grep ^GIT_PROTOCOL env.trace +' + # Test protocol v2 with 'http://' transport # . "$TEST_DIRECTORY"/lib-httpd.sh diff --git a/transport.c b/transport.c index 906dbad5a0..fa9bc3be08 100644 --- a/transport.c +++ b/transport.c @@ -279,8 +279,12 @@ static int connect_setup(struct transport *transport, int for_push) } data->conn = git_connect(data->fd, transport->url, - for_push ? data->options.receivepack : - data->options.uploadpack, + for_push ? + "git-receive-pack" : + "git-upload-pack", + for_push ? + data->options.receivepack : + data->options.uploadpack, flags); return 0; @@ -914,7 +918,7 @@ static int connect_git(struct transport *transport, const char *name, { struct git_transport_data *data = transport->data; data->conn = git_connect(data->fd, transport->url, - executable, 0); + name, executable, 0); fd[0] = data->fd[0]; fd[1] = data->fd[1]; return 0;