grep "server-option=world" log
'
+test_expect_success 'server-options from configuration are used by ls-remote' '
+ test_when_finished "rm -rf log myclone" &&
+ git clone "file://$(pwd)/file_parent" myclone &&
+ cat >expect <<-EOF &&
+ $(git -C file_parent rev-parse refs/heads/main)$(printf "\t")refs/heads/main
+ EOF
+
+ # Default server options from configuration are used
+ git -C myclone config --add remote.origin.serverOption foo &&
+ git -C myclone config --add remote.origin.serverOption bar &&
+ GIT_TRACE_PACKET="$(pwd)/log" git -C myclone -c protocol.version=2 \
+ ls-remote origin main >actual &&
+ test_cmp expect actual &&
+ test_grep "ls-remote> server-option=foo" log &&
+ test_grep "ls-remote> server-option=bar" log &&
+ rm -f log &&
+
+ # Empty value of remote.<name>.serverOption clears the list
+ git -C myclone config --add remote.origin.serverOption "" &&
+ git -C myclone config --add remote.origin.serverOption tar &&
+ GIT_TRACE_PACKET="$(pwd)/log" git -C myclone -c protocol.version=2 \
+ ls-remote origin main >actual &&
+ test_cmp expect actual &&
+ test_grep "ls-remote> server-option=tar" log &&
+ test_grep ! "ls-remote> server-option=foo" log &&
+ test_grep ! "ls-remote> server-option=bar" log &&
+ rm -f log &&
+
+ # Server option from command line overrides those from configuration
+ GIT_TRACE_PACKET="$(pwd)/log" git -C myclone -c protocol.version=2 \
+ ls-remote -o hello -o world origin main >actual &&
+ test_cmp expect actual &&
+ test_grep "ls-remote> server-option=hello" log &&
+ test_grep "ls-remote> server-option=world" log &&
+ test_grep ! "ls-remote> server-option=tar" log
+'
+
test_expect_success 'warn if using server-option with ls-remote with legacy protocol' '
test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 git -c protocol.version=0 \
ls-remote -o hello -o world "file://$(pwd)/file_parent" main 2>err &&
grep "server-option=world" log
'
+test_expect_success 'server-options from configuration are used by git-fetch' '
+ test_when_finished "rm -rf log myclone" &&
+ git clone "file://$(pwd)/file_parent" myclone &&
+ git -C file_parent log -1 --format=%s >expect &&
+
+ # Default server options from configuration are used
+ git -C myclone config --add remote.origin.serverOption foo &&
+ git -C myclone config --add remote.origin.serverOption bar &&
+ GIT_TRACE_PACKET="$(pwd)/log" git -C myclone -c protocol.version=2 \
+ fetch origin main &&
+ git -C myclone log -1 --format=%s origin/main >actual &&
+ test_cmp expect actual &&
+ test_grep "fetch> server-option=foo" log &&
+ test_grep "fetch> server-option=bar" log &&
+ rm -f log &&
+
+ # Empty value of remote.<name>.serverOption clears the list
+ git -C myclone config --add remote.origin.serverOption "" &&
+ git -C myclone config --add remote.origin.serverOption tar &&
+ GIT_TRACE_PACKET="$(pwd)/log" git -C myclone -c protocol.version=2 \
+ fetch origin main &&
+ git -C myclone log -1 --format=%s origin/main >actual &&
+ test_cmp expect actual &&
+ test_grep "fetch> server-option=tar" log &&
+ test_grep ! "fetch> server-option=foo" log &&
+ test_grep ! "fetch> server-option=bar" log &&
+ rm -f log &&
+
+ # Server option from command line overrides those from configuration
+ GIT_TRACE_PACKET="$(pwd)/log" git -C myclone -c protocol.version=2 \
+ fetch -o hello -o world origin main &&
+ git -C myclone log -1 --format=%s origin/main >actual &&
+ test_cmp expect actual &&
+ test_grep "fetch> server-option=hello" log &&
+ test_grep "fetch> server-option=world" log &&
+ test_grep ! "fetch> server-option=tar" log
+'
+
test_expect_success 'warn if using server-option with fetch with legacy protocol' '
test_when_finished "rm -rf temp_child" &&
grep "server-option=world" log
'
+test_expect_success 'server-options from configuration are used by git-clone' '
+ test_when_finished "rm -rf log myclone" &&
+
+ # Default server options from configuration are used
+ GIT_TRACE_PACKET="$(pwd)/log" git -c protocol.version=2 \
+ -c remote.origin.serverOption=foo -c remote.origin.serverOption=bar \
+ clone "file://$(pwd)/file_parent" myclone &&
+ test_grep "clone> server-option=foo" log &&
+ test_grep "clone> server-option=bar" log &&
+ rm -rf log myclone &&
+
+ # Empty value of remote.<name>.serverOption clears the list
+ GIT_TRACE_PACKET="$(pwd)/log" git -c protocol.version=2 \
+ -c remote.origin.serverOption=foo -c remote.origin.serverOption=bar \
+ -c remote.origin.serverOption= -c remote.origin.serverOption=tar \
+ clone "file://$(pwd)/file_parent" myclone &&
+ test_grep "clone> server-option=tar" log &&
+ test_grep ! "clone> server-option=foo" log &&
+ test_grep ! "clone> server-option=bar" log &&
+ rm -rf log myclone &&
+
+ # Server option from command line overrides those from configuration
+ GIT_TRACE_PACKET="$(pwd)/log" git -c protocol.version=2 \
+ -c remote.origin.serverOption=tar \
+ clone --server-option=hello --server-option=world \
+ "file://$(pwd)/file_parent" myclone &&
+ test_grep "clone> server-option=hello" log &&
+ test_grep "clone> server-option=world" log &&
+ test_grep ! "clone> server-option=tar" log
+'
+
test_expect_success 'warn if using server-option with clone with legacy protocol' '
test_when_finished "rm -rf myclone" &&
test_grep "server options require protocol version 2 or later" err
'
+test_expect_success 'server-option configuration with legacy protocol is ok' '
+ test_when_finished "rm -rf myclone" &&
+
+ env GIT_TEST_PROTOCOL_VERSION=0 git -c protocol.version=0 \
+ -c remote.origin.serverOption=foo -c remote.origin.serverOption=bar \
+ clone "file://$(pwd)/file_parent" myclone
+'
+
+test_expect_success 'invalid server-option configuration' '
+ test_when_finished "rm -rf myclone" &&
+
+ test_must_fail git -c protocol.version=2 \
+ -c remote.origin.serverOption \
+ clone "file://$(pwd)/file_parent" myclone 2>err &&
+ test_grep "error: missing value for '\''remote.origin.serveroption'\''" err
+'
+
test_expect_success 'upload-pack respects config using protocol v2' '
git init server &&
write_script server/.git/hook <<-\EOF &&