Skip to content

Commit 094f78a

Browse files
blanetgitster
authored andcommitted
transport.c::handshake: make use of server options from remote
Utilize the `server_options` from the corresponding remote during the handshake in `transport.c` when Git protocol v2 is detected. This helps initialize the `server_options` in `transport.h:transport` if no server options are set for the transport (typically via `--server-option` or `-o`). While another potential place to incorporate server options from the remote is in `transport.c:transport_get`, setting server options for a transport using a protocol other than v2 could lead to unexpected errors (see `transport.c:die_if_server_options`). Relevant tests and documentation have been updated accordingly. Signed-off-by: Xing Xin <[email protected]> Reviewed-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 72da5cf commit 094f78a

File tree

5 files changed

+135
-0
lines changed

5 files changed

+135
-0
lines changed

Documentation/fetch-options.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,9 @@ endif::git-pull[]
305305
unknown ones, is server-specific.
306306
When multiple `--server-option=<option>` are given, they are all
307307
sent to the other side in the order listed on the command line.
308+
When no `--server-option=<option>` is given from the command line,
309+
the values of configuration variable `remote.<name>.serverOption`
310+
are used instead.
308311

309312
--show-forced-updates::
310313
By default, git checks if a branch is force-updated during

Documentation/git-clone.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,9 @@ objects from the source repository into a pack in the cloned repository.
149149
unknown ones, is server-specific.
150150
When multiple ++--server-option=++__<option>__ are given, they are all
151151
sent to the other side in the order listed on the command line.
152+
When no ++--server-option=++__<option>__ is given from the command
153+
line, the values of configuration variable `remote.<name>.serverOption`
154+
are used instead.
152155

153156
`-n`::
154157
`--no-checkout`::

Documentation/git-ls-remote.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ OPTIONS
8181
character.
8282
When multiple `--server-option=<option>` are given, they are all
8383
sent to the other side in the order listed on the command line.
84+
When no `--server-option=<option>` is given from the command line,
85+
the values of configuration variable `remote.<name>.serverOption`
86+
are used instead.
8487

8588
<repository>::
8689
The "remote" repository to query. This parameter can be

t/t5702-protocol-v2.sh

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,43 @@ test_expect_success 'server-options are sent when using ls-remote' '
185185
grep "server-option=world" log
186186
'
187187

188+
test_expect_success 'server-options from configuration are used by ls-remote' '
189+
test_when_finished "rm -rf log myclone" &&
190+
git clone "file://$(pwd)/file_parent" myclone &&
191+
cat >expect <<-EOF &&
192+
$(git -C file_parent rev-parse refs/heads/main)$(printf "\t")refs/heads/main
193+
EOF
194+
195+
# Default server options from configuration are used
196+
git -C myclone config --add remote.origin.serverOption foo &&
197+
git -C myclone config --add remote.origin.serverOption bar &&
198+
GIT_TRACE_PACKET="$(pwd)/log" git -C myclone -c protocol.version=2 \
199+
ls-remote origin main >actual &&
200+
test_cmp expect actual &&
201+
test_grep "ls-remote> server-option=foo" log &&
202+
test_grep "ls-remote> server-option=bar" log &&
203+
rm -f log &&
204+
205+
# Empty value of remote.<name>.serverOption clears the list
206+
git -C myclone config --add remote.origin.serverOption "" &&
207+
git -C myclone config --add remote.origin.serverOption tar &&
208+
GIT_TRACE_PACKET="$(pwd)/log" git -C myclone -c protocol.version=2 \
209+
ls-remote origin main >actual &&
210+
test_cmp expect actual &&
211+
test_grep "ls-remote> server-option=tar" log &&
212+
test_grep ! "ls-remote> server-option=foo" log &&
213+
test_grep ! "ls-remote> server-option=bar" log &&
214+
rm -f log &&
215+
216+
# Server option from command line overrides those from configuration
217+
GIT_TRACE_PACKET="$(pwd)/log" git -C myclone -c protocol.version=2 \
218+
ls-remote -o hello -o world origin main >actual &&
219+
test_cmp expect actual &&
220+
test_grep "ls-remote> server-option=hello" log &&
221+
test_grep "ls-remote> server-option=world" log &&
222+
test_grep ! "ls-remote> server-option=tar" log
223+
'
224+
188225
test_expect_success 'warn if using server-option with ls-remote with legacy protocol' '
189226
test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 git -c protocol.version=0 \
190227
ls-remote -o hello -o world "file://$(pwd)/file_parent" main 2>err &&
@@ -381,6 +418,44 @@ test_expect_success 'server-options are sent when fetching' '
381418
grep "server-option=world" log
382419
'
383420

421+
test_expect_success 'server-options from configuration are used by git-fetch' '
422+
test_when_finished "rm -rf log myclone" &&
423+
git clone "file://$(pwd)/file_parent" myclone &&
424+
git -C file_parent log -1 --format=%s >expect &&
425+
426+
# Default server options from configuration are used
427+
git -C myclone config --add remote.origin.serverOption foo &&
428+
git -C myclone config --add remote.origin.serverOption bar &&
429+
GIT_TRACE_PACKET="$(pwd)/log" git -C myclone -c protocol.version=2 \
430+
fetch origin main &&
431+
git -C myclone log -1 --format=%s origin/main >actual &&
432+
test_cmp expect actual &&
433+
test_grep "fetch> server-option=foo" log &&
434+
test_grep "fetch> server-option=bar" log &&
435+
rm -f log &&
436+
437+
# Empty value of remote.<name>.serverOption clears the list
438+
git -C myclone config --add remote.origin.serverOption "" &&
439+
git -C myclone config --add remote.origin.serverOption tar &&
440+
GIT_TRACE_PACKET="$(pwd)/log" git -C myclone -c protocol.version=2 \
441+
fetch origin main &&
442+
git -C myclone log -1 --format=%s origin/main >actual &&
443+
test_cmp expect actual &&
444+
test_grep "fetch> server-option=tar" log &&
445+
test_grep ! "fetch> server-option=foo" log &&
446+
test_grep ! "fetch> server-option=bar" log &&
447+
rm -f log &&
448+
449+
# Server option from command line overrides those from configuration
450+
GIT_TRACE_PACKET="$(pwd)/log" git -C myclone -c protocol.version=2 \
451+
fetch -o hello -o world origin main &&
452+
git -C myclone log -1 --format=%s origin/main >actual &&
453+
test_cmp expect actual &&
454+
test_grep "fetch> server-option=hello" log &&
455+
test_grep "fetch> server-option=world" log &&
456+
test_grep ! "fetch> server-option=tar" log
457+
'
458+
384459
test_expect_success 'warn if using server-option with fetch with legacy protocol' '
385460
test_when_finished "rm -rf temp_child" &&
386461
@@ -404,6 +479,37 @@ test_expect_success 'server-options are sent when cloning' '
404479
grep "server-option=world" log
405480
'
406481

482+
test_expect_success 'server-options from configuration are used by git-clone' '
483+
test_when_finished "rm -rf log myclone" &&
484+
485+
# Default server options from configuration are used
486+
GIT_TRACE_PACKET="$(pwd)/log" git -c protocol.version=2 \
487+
-c remote.origin.serverOption=foo -c remote.origin.serverOption=bar \
488+
clone "file://$(pwd)/file_parent" myclone &&
489+
test_grep "clone> server-option=foo" log &&
490+
test_grep "clone> server-option=bar" log &&
491+
rm -rf log myclone &&
492+
493+
# Empty value of remote.<name>.serverOption clears the list
494+
GIT_TRACE_PACKET="$(pwd)/log" git -c protocol.version=2 \
495+
-c remote.origin.serverOption=foo -c remote.origin.serverOption=bar \
496+
-c remote.origin.serverOption= -c remote.origin.serverOption=tar \
497+
clone "file://$(pwd)/file_parent" myclone &&
498+
test_grep "clone> server-option=tar" log &&
499+
test_grep ! "clone> server-option=foo" log &&
500+
test_grep ! "clone> server-option=bar" log &&
501+
rm -rf log myclone &&
502+
503+
# Server option from command line overrides those from configuration
504+
GIT_TRACE_PACKET="$(pwd)/log" git -c protocol.version=2 \
505+
-c remote.origin.serverOption=tar \
506+
clone --server-option=hello --server-option=world \
507+
"file://$(pwd)/file_parent" myclone &&
508+
test_grep "clone> server-option=hello" log &&
509+
test_grep "clone> server-option=world" log &&
510+
test_grep ! "clone> server-option=tar" log
511+
'
512+
407513
test_expect_success 'warn if using server-option with clone with legacy protocol' '
408514
test_when_finished "rm -rf myclone" &&
409515
@@ -415,6 +521,23 @@ test_expect_success 'warn if using server-option with clone with legacy protocol
415521
test_grep "server options require protocol version 2 or later" err
416522
'
417523

524+
test_expect_success 'server-option configuration with legacy protocol is ok' '
525+
test_when_finished "rm -rf myclone" &&
526+
527+
env GIT_TEST_PROTOCOL_VERSION=0 git -c protocol.version=0 \
528+
-c remote.origin.serverOption=foo -c remote.origin.serverOption=bar \
529+
clone "file://$(pwd)/file_parent" myclone
530+
'
531+
532+
test_expect_success 'invalid server-option configuration' '
533+
test_when_finished "rm -rf myclone" &&
534+
535+
test_must_fail git -c protocol.version=2 \
536+
-c remote.origin.serverOption \
537+
clone "file://$(pwd)/file_parent" myclone 2>err &&
538+
test_grep "error: missing value for '\''remote.origin.serveroption'\''" err
539+
'
540+
418541
test_expect_success 'upload-pack respects config using protocol v2' '
419542
git init server &&
420543
write_script server/.git/hook <<-\EOF &&

transport.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,9 @@ static struct ref *handshake(struct transport *transport, int for_push,
334334
data->version = discover_version(&reader);
335335
switch (data->version) {
336336
case protocol_v2:
337+
if ((!transport->server_options || !transport->server_options->nr) &&
338+
transport->remote->server_options.nr)
339+
transport->server_options = &transport->remote->server_options;
337340
if (server_feature_v2("session-id", &server_sid))
338341
trace2_data_string("transfer", NULL, "server-sid", server_sid);
339342
if (must_list_refs)

0 commit comments

Comments
 (0)