From: "ZheNing Hu via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: "Junio C Hamano" <gitster@pobox.com>,
"Shawn O. Pearce" <spearce@spearce.org>,
"Ævar Arnfjörð Bjarmason" <avarab@gmail.com>,
"Zeger-Jan van de Weg" <zegerjan@gitlab.com>,
"ZheNing Hu" <adlternative@gmail.com>,
"ZheNing Hu" <adlternative@gmail.com>
Subject: [PATCH] [RFC] transport: add --show-service option
Date: Mon, 24 Apr 2023 13:17:21 +0000 [thread overview]
Message-ID: <pull.1523.git.1682342241825.gitgitgadget@gmail.com> (raw)
From: ZheNing Hu <adlternative@gmail.com>
Without using protocol v2, the git server needs to send a pktline
"# service=$servicename" to the git client first. This often
requires the git server to implement it independently, but it can
be delegated to the `git receive-pack` and `git upload-pack` to complete
the work proactively. Therefore, the `--show-service` option is added
to `git receive-pack` and `git upload-pack`, which can be used to send
the "# service=$servicename" pktline, making the logic of the git
server more concise.
Note that this `--show-service` option can only be used together with
`--http-backend-info-refs` and it is not applicable when using protocol v2.
Signed-off-by: ZheNing Hu <adlternative@gmail.com>
---
[RFC] transport: add --show-service option
When the protocol is not v2, the git client requires that the first
pktline reply for info refs be "# service=servicename", which requires
the git server to implement pktline capability, e.g. [1] , which may be
a bit cumbersome.
Delegating this feature to git upload-pack and git receive-pack via
"--show-service" can simplify server implementation.
v1. add --show-service to git upload-pack and git receive-pack.
[1]:
https://gitlab.com/gitlab-org/gitaly/-/blob/master/internal/gitaly/service/smarthttp/inforefs.go#L82
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1523%2Fadlternative%2Fzh%2Finfo-ref-service-output-opt-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1523/adlternative/zh/info-ref-service-output-opt-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/1523
Documentation/git-receive-pack.txt | 10 +++
Documentation/git-upload-pack.txt | 13 +++-
builtin/receive-pack.c | 14 +++-
builtin/upload-pack.c | 17 +++-
http-backend.c | 7 +-
t/t5555-http-smart-common.sh | 120 +++++++++++++++++++++++++++++
6 files changed, 171 insertions(+), 10 deletions(-)
diff --git a/Documentation/git-receive-pack.txt b/Documentation/git-receive-pack.txt
index 65ff518ccff..e16d364f394 100644
--- a/Documentation/git-receive-pack.txt
+++ b/Documentation/git-receive-pack.txt
@@ -46,6 +46,16 @@ OPTIONS
`$GIT_URL/info/refs?service=git-receive-pack` requests. See
`--http-backend-info-refs` in linkgit:git-upload-pack[1].
+--show-service::
+ Output the "# service=git-receive-pack" pktline and the
+ "0000" flush pktline firstly. Since the git client needs
+ the git server to send the first pktline
+ "# service=$servicename", this option allows the git
+ server to delegate the functionality of sending this pktline
+ to `git-receive-pack`.
+ Note that this option can only be used together with
+ `--http-backend-info-refs`.
+
PRE-RECEIVE HOOK
----------------
Before any ref is updated, if $GIT_DIR/hooks/pre-receive file exists
diff --git a/Documentation/git-upload-pack.txt b/Documentation/git-upload-pack.txt
index b656b475675..7052708d03e 100644
--- a/Documentation/git-upload-pack.txt
+++ b/Documentation/git-upload-pack.txt
@@ -10,7 +10,7 @@ SYNOPSIS
--------
[verse]
'git-upload-pack' [--[no-]strict] [--timeout=<n>] [--stateless-rpc]
- [--advertise-refs] <directory>
+ [--advertise-refs] [--show-service] <directory>
DESCRIPTION
-----------
@@ -44,6 +44,17 @@ OPTIONS
documentation. Also understood by
linkgit:git-receive-pack[1].
+--show-service::
+ Output the "# service=git-upload-pack" pktline and the
+ "0000" flush pktline firstly. Since the git client needs
+ the git server to send the first pktline
+ "# service=$servicename", this option allows the git
+ server to delegate the functionality of sending this pktline
+ to `git-upload-pack`.
+ Note that this option can only be used together with
+ `--http-backend-info-refs` and it is not applicable when
+ using protocol v2.
+
<directory>::
The repository to sync from.
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index 9109552533d..eb45c1f72af 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -2485,6 +2485,7 @@ static int delete_only(struct command *commands)
int cmd_receive_pack(int argc, const char **argv, const char *prefix)
{
int advertise_refs = 0;
+ int show_service = 0;
struct command *commands;
struct oid_array shallow = OID_ARRAY_INIT;
struct oid_array ref = OID_ARRAY_INIT;
@@ -2497,8 +2498,10 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
OPT_HIDDEN_BOOL(0, "http-backend-info-refs", &advertise_refs, NULL),
OPT_ALIAS(0, "advertise-refs", "http-backend-info-refs"),
OPT_HIDDEN_BOOL(0, "reject-thin-pack-for-testing", &reject_thin, NULL),
+ OPT_BOOL(0, "show-service", &show_service, N_("show service information")),
OPT_END()
};
+ enum protocol_version version = determine_protocol_version_server();
packet_trace_identity("receive-pack");
@@ -2525,7 +2528,16 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
else if (0 <= receive_unpack_limit)
unpack_limit = receive_unpack_limit;
- switch (determine_protocol_version_server()) {
+ if (show_service) {
+ if (!advertise_refs)
+ die(_("options '%s' and '%s' should be used together"), "--show-service", "--http-backend-info-refs");
+ if (version != protocol_v2) {
+ packet_write_fmt(1, "# service=git-receive-pack\n");
+ packet_flush(1);
+ }
+ }
+
+ switch (version) {
case protocol_v2:
/*
* push support for protocol v2 has not been implemented yet,
diff --git a/builtin/upload-pack.c b/builtin/upload-pack.c
index beb9dd08610..e84eb3735b4 100644
--- a/builtin/upload-pack.c
+++ b/builtin/upload-pack.c
@@ -11,7 +11,7 @@
static const char * const upload_pack_usage[] = {
N_("git-upload-pack [--[no-]strict] [--timeout=<n>] [--stateless-rpc]\n"
- " [--advertise-refs] <directory>"),
+ " [--advertise-refs] [--show-service] <directory>"),
NULL
};
@@ -22,6 +22,7 @@ int cmd_upload_pack(int argc, const char **argv, const char *prefix)
int advertise_refs = 0;
int stateless_rpc = 0;
int timeout = 0;
+ int show_service = 0;
struct option options[] = {
OPT_BOOL(0, "stateless-rpc", &stateless_rpc,
N_("quit after a single request/response exchange")),
@@ -32,8 +33,10 @@ int cmd_upload_pack(int argc, const char **argv, const char *prefix)
N_("do not try <directory>/.git/ if <directory> is no Git directory")),
OPT_INTEGER(0, "timeout", &timeout,
N_("interrupt transfer after <n> seconds of inactivity")),
+ OPT_BOOL(0, "show-service", &show_service, N_("show service information")),
OPT_END()
};
+ enum protocol_version version = determine_protocol_version_server();
packet_trace_identity("upload-pack");
read_replace_refs = 0;
@@ -50,7 +53,17 @@ int cmd_upload_pack(int argc, const char **argv, const char *prefix)
if (!enter_repo(dir, strict))
die("'%s' does not appear to be a git repository", dir);
- switch (determine_protocol_version_server()) {
+
+ if (show_service) {
+ if (!advertise_refs)
+ die(_("options '%s' and '%s' should be used together"), "--show-service", "--http-backend-info-refs");
+ if (version != protocol_v2) {
+ packet_write_fmt(1, "# service=git-upload-pack\n");
+ packet_flush(1);
+ }
+ }
+
+ switch (version) {
case protocol_v2:
if (advertise_refs)
protocol_v2_advertise_capabilities();
diff --git a/http-backend.c b/http-backend.c
index 89aad1b42c7..74c2c7bb606 100644
--- a/http-backend.c
+++ b/http-backend.c
@@ -539,6 +539,7 @@ static void get_info_refs(struct strbuf *hdr, char *arg UNUSED)
if (service_name) {
const char *argv[] = {NULL /* service name */,
"--http-backend-info-refs",
+ "--show-service",
".", NULL};
struct rpc_service *svc = select_service(hdr, service_name);
@@ -547,12 +548,6 @@ static void get_info_refs(struct strbuf *hdr, char *arg UNUSED)
hdr_str(hdr, content_type, buf.buf);
end_headers(hdr);
-
- if (determine_protocol_version_server() != protocol_v2) {
- packet_write_fmt(1, "# service=git-%s\n", svc->name);
- packet_flush(1);
- }
-
argv[0] = svc->name;
run_service(argv, 0);
diff --git a/t/t5555-http-smart-common.sh b/t/t5555-http-smart-common.sh
index b1cfe8b7dba..32431266eb9 100755
--- a/t/t5555-http-smart-common.sh
+++ b/t/t5555-http-smart-common.sh
@@ -159,4 +159,124 @@ test_expect_success 'git receive-pack --advertise-refs: v2' '
test_cmp actual expect
'
+test_expect_success 'git upload-pack --advertise-refs --show-service: v0' '
+ # With no specified protocol
+ cat >expect <<-EOF &&
+ # service=git-upload-pack
+ 0000
+ $(git rev-parse HEAD) HEAD
+ $(git rev-parse HEAD) $(git symbolic-ref HEAD)
+ 0000
+ EOF
+
+ git upload-pack --advertise-refs --show-service . >out 2>err &&
+ test-tool pkt-line unpack <out >actual &&
+ test_must_be_empty err &&
+ test_cmp actual expect &&
+
+ # With explicit v0
+ GIT_PROTOCOL=version=0 \
+ git upload-pack --advertise-refs --show-service . >out 2>err &&
+ test-tool pkt-line unpack <out >actual 2>err &&
+ test_must_be_empty err &&
+ test_cmp actual expect
+
+'
+
+test_expect_success 'git receive-pack --advertise-refs --show-service: v0' '
+ # With no specified protocol
+ cat >expect <<-EOF &&
+ # service=git-receive-pack
+ 0000
+ $(git rev-parse HEAD) $(git symbolic-ref HEAD)
+ 0000
+ EOF
+
+ git receive-pack --advertise-refs --show-service . >out 2>err &&
+ test-tool pkt-line unpack <out >actual &&
+ test_must_be_empty err &&
+ test_cmp actual expect &&
+
+ # With explicit v0
+ GIT_PROTOCOL=version=0 \
+ git receive-pack --advertise-refs --show-service . >out 2>err &&
+ test-tool pkt-line unpack <out >actual 2>err &&
+ test_must_be_empty err &&
+ test_cmp actual expect
+
+'
+
+test_expect_success 'git upload-pack --advertise-refs --show-service: v1' '
+ # With no specified protocol
+ cat >expect <<-EOF &&
+ # service=git-upload-pack
+ 0000
+ version 1
+ $(git rev-parse HEAD) HEAD
+ $(git rev-parse HEAD) $(git symbolic-ref HEAD)
+ 0000
+ EOF
+
+ GIT_PROTOCOL=version=1 \
+ git upload-pack --advertise-refs --show-service . >out &&
+
+ test-tool pkt-line unpack <out >actual 2>err &&
+ test_must_be_empty err &&
+ test_cmp actual expect
+'
+
+test_expect_success 'git receive-pack --advertise-refs --show-service: v1' '
+ # With no specified protocol
+ cat >expect <<-EOF &&
+ # service=git-receive-pack
+ 0000
+ version 1
+ $(git rev-parse HEAD) $(git symbolic-ref HEAD)
+ 0000
+ EOF
+
+ GIT_PROTOCOL=version=1 \
+ git receive-pack --advertise-refs --show-service . >out &&
+
+ test-tool pkt-line unpack <out >actual 2>err &&
+ test_must_be_empty err &&
+ test_cmp actual expect
+'
+
+test_expect_success 'git upload-pack --advertise-refs --show-service: v2' '
+ cat >expect <<-EOF &&
+ version 2
+ agent=FAKE
+ ls-refs=unborn
+ fetch=shallow wait-for-done
+ server-option
+ object-format=$(test_oid algo)
+ object-info
+ 0000
+ EOF
+
+ GIT_PROTOCOL=version=2 \
+ GIT_USER_AGENT=FAKE \
+ git upload-pack --advertise-refs --show-service . >out 2>err &&
+
+ test-tool pkt-line unpack <out >actual &&
+ test_must_be_empty err &&
+ test_cmp actual expect
+'
+
+test_expect_success 'git receive-pack --advertise-refs --show-service: v2' '
+ # There is no v2 yet for receive-pack, implicit v0
+ cat >expect <<-EOF &&
+ $(git rev-parse HEAD) $(git symbolic-ref HEAD)
+ 0000
+ EOF
+
+ GIT_PROTOCOL=version=2 \
+ git receive-pack --advertise-refs --show-service . >out 2>err &&
+
+ test-tool pkt-line unpack <out >actual &&
+ test_must_be_empty err &&
+ test_cmp actual expect
+'
+
test_done
base-commit: 7580f92ffa970b9484ac214f7b53cec5e26ca4bc
--
gitgitgadget
next reply other threads:[~2023-04-24 13:18 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-04-24 13:17 ZheNing Hu via GitGitGadget [this message]
2023-04-25 4:02 ` [PATCH] [RFC] transport: add --show-service option Junio C Hamano
2023-04-27 4:35 ` ZheNing Hu
2023-04-27 5:50 ` Junio C Hamano
2023-05-04 15:28 ` [PATCH v2] " ZheNing Hu via GitGitGadget
2023-05-10 8:15 ` ZheNing Hu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=pull.1523.git.1682342241825.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=adlternative@gmail.com \
--cc=avarab@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=spearce@spearce.org \
--cc=zegerjan@gitlab.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.